模型導入unity后,可以使用unity的Inspector面板對模型在某個坐標軸上進行平移、旋轉和縮放操作(如圖1)。
Inspector面板提供功能是所見即所得的,調整后立刻可以看到效果,相當的方便。但是這些功能還不能完全滿足游戲開發的要求,比如為了減輕美工的工作量一些游戲對場景中的模型標准作出了一些規定,使這些模塊化的小模型能按照一定的規律拼接成豐富多樣的大模型。拼接過程往往要對模型的local coordinates進行調整才能最終形成一個“無縫”的大模型,而這個過程常常是在游戲運行時進行(或者地圖初始化時),因此需要引擎提供修改模型mesh的接口。十分幸運的是unity提供了這樣的接口。
Mesh and MeshFilter
需要修改模型的網格數據,首先第一步是要想辦法獲得模型的mesh,這里我們需要Mesh Filter,unity文檔中的解釋如下:
The Mesh Filter takes a mesh from your assets and passes it to the Mesh Renderer for rendering on the screen.
如上圖,Robot手里拿的槍的網格數據保存在以gun_model命名的Mesh里,而這個Mesh則隸屬於Gun_model的MeshFilter。知道了網格數據保存的位置,接下來需要做的就是獲取這些數據並修改它們。下面使用一個簡單的cliff模型為例子介紹如何修改模型的網格數據。
Simple Example
首先來看原始的模型長什么樣?
現在需要修改模型的網格數據,把模型最高點的高度坐標挑高一倍,代碼如下:
1: using UnityEngine;
2: using System.Collections;
3:
4: [RequireComponent(typeof(MeshFilter))]
5: public class example : MonoBehaviour {
6: void Update() {
7: Mesh mesh = GetComponent<MeshFilter>().mesh;
8: Vector3 [] vertices = mesh.vertices;
9:
10: int p = 0;
11: int flag = -1;
12: float maxheight = 0.0F;
13: while (p < vertices.Length) {
14: if(vertices[p].z > maxheight) {
15: maxheight = vertices[p].z;
16: flag = p;
17: }
18: p++;
19: }
20: vertices[flag] += new Vector3(0, 0, maxheight);
21:
22: mesh.vertices = vertices;
23: mesh.RecalculateNormals();
24: }
25: }
注意:本例所使用的模型的local坐標系的z軸相當於unity的y軸,因此上述代碼時對z軸進行修改。代碼運行的結果如下:
是不是很簡單!unity強大的接口以及較為詳細的文檔對開發者來說確實是一個福音,另外使用C#編程對於我這苦逼的不合格C++程序員來說確實很爽!
另外有一點值得注意:上述代碼所對應的腳本一定要drag到GameObject里MeshFilter的擁有者,才能使代碼生效。如下圖5必須要把script拖拽到Cliffs01才能生效,因為在cliffs_1cm的GameObject里只有Cliffs01擁有MeshFilter(如圖6)
圖 6
References:
[1]http://docs.unity3d.com/Documentation/ScriptReference/MeshFilter-mesh.html
[2]http://docs.unity3d.com/Documentation/ScriptReference/Mesh.html