unity, 用脚本创建mesh
创建一个空gameObject,添加Mesh Filter和Mesh Renderer两个component,再添加一个脚本createMeshScript:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class createMeshScript : MonoBehaviour {
void Awake() {
gameObject.GetComponent<MeshFilter> ().mesh = CreateMesh (1,1);
}
Mesh CreateMesh(float width, float height)
{
Mesh m = new Mesh();
m.name = "ScriptedMesh";
//note: unity is left-hand system
m.vertices = new Vector3[] {
new Vector3(-width/2, -height/2, 0),
new Vector3(-width/2, height/2, 0),
new Vector3(width/2, height/2, 0),
new Vector3(width/2, -height/2, 0)
};
m.uv = new Vector2[] {
new Vector2 (0, 0),
new Vector2 (0, 1),
new Vector2 (1, 1),
new Vector2 (1, 0)
};
m.triangles = new int[] { 0, 1, 2, 0, 2, 3};
m.RecalculateNormals();
m.RecalculateBounds();
return m;
}
}
此时可以看到Inspector中Mesh Filter->Mesh显示为ScriptedMesh(因为我们在代码中为它命名是scriptedMesh)。
此时创建的mesh没有材质,显示为紫色,新建一个Material拖放到Mesh Renderer->Materials->Element 0上,完成mesh的创建。
运行程序,可以看到脚本创建的mesh如图:
另外需要注意的是:
1,unity中是坐标系统是左手系,如果不注意这一点把顶点顺序(法线)搞反了,可能画出来的东西因背面剔除而看不到。
2,mesh.vertices要用局部坐标。
参考:
http://blog.nobel-joergensen.com/2010/12/25/procedural-generated-mesh-in-unity/
http://answers.unity3d.com/questions/139808/creating-a-plane-mesh-directly-from-code.html
----补充:(2015-5-23)
下面尝试创建一个复杂一点儿的面片:
将前面的脚本改成:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class createMeshScript : MonoBehaviour {
void Awake() {
gameObject.GetComponent<MeshFilter> ().mesh = CreateRandomPlane (1,1,3,3,true);//false
}
Mesh CreateCustomPlane(float width, float height,int nRow,int nCol,bool isAddRandom){
Mesh m = new Mesh();
m.name = "customPlane";
//note: unity is left-hand system
Vector3 LU = new Vector3 (-width/2,height/2,0);
float dx = width / nCol;
float dy = height / nRow;
int vertCount = (nRow + 1) * (nCol + 1);
int triangleCount = nRow * nCol * 2;
Vector3[] vertices=new Vector3[vertCount];
Vector2[] uv=new Vector2[vertCount];
int[] IDs=new int[triangleCount*3];
for (int i=0; i<nRow+1; i++) {
for(int j=0;j<nCol+1;j++){
Vector3 v=LU+new Vector3(dx*j,-dy*i,0);
Vector2 texCoord=new Vector2(dx*j/width,1-dy*i/height);
if(isAddRandom){//add random
v.z=(Random.value*2-1)*0.1f;
}
vertices[i*(nCol+1)+j]=v;
uv[i*(nCol+1)+j]=texCoord;
}
}
for (int i=0; i<nRow; i++) {
for(int j=0;j<nCol;j++){
//quad[i][j]
int LUID=i*(nCol+1)+j;
int LDID=LUID+(nCol+1);
int RUID=LUID+1;
int RDID=LDID+1;
//quad[i][j] is triangle[2*(i*4+j)] and triangle[2*(i*4+j)+1]
//triangle[2*(i*4+j)] is {IDs[2*(i*4+j)*3],IDs[2*(i*4+j)*3+1],IDs[2*(i*4+j)*3+2]}
IDs[2*(i*nCol+j)*3]=LUID;
IDs[2*(i*nCol+j)*3+1]=RUID;
IDs[2*(i*nCol+j)*3+2]=LDID;
//triangle[2*(i*4+j)+1] is {IDs[(2*(i*4+j)+1)*3],IDs[(2*(i*4+j)*3+1)*3+1],IDs[(2*(i*4+j)*3+2)*3+2]}
IDs[(2*(i*nCol+j)+1)*3]=LDID;
IDs[(2*(i*nCol+j)+1)*3+1]=RUID;
IDs[(2*(i*nCol+j)+1)*3+2]=RDID;
}
}
m.vertices = vertices;
m.uv = uv;
m.triangles = IDs;
m.RecalculateNormals();
m.RecalculateBounds();
return m;
}
}
运行结果:
左边是isAddRandom取false,右边是isAddRandom取true。
注:脚本中的m.RecalculateBounds()可能是多余的,因为Mesh.RecalculateBounds的官方文档中写道:After modifying vertices you should call this function to ensure the bounding volume is correct. Assigning triangles will automatically Recalculate the bounding volume.