Unity3D之Mesh基础

教程一


Unity3D之Mesh绘制多边形

一些知识点的说明记录与补充:

1、

总的来说绘制平面的思想十分简单,就是将需要的平面拆分成几个三角形然后进行绘制就可以啦,主要的思路就在于三角形的拆分。如果说一个平面有7个顶点,我们把它们分别编号0到6,拆分情况如图所示:

即:如果用n来表示顶点的个数,那么在同一个平面内,可以分割的三角形个数是:n-2;

2、

在这里,我们选择应用Mesh Filter组件来进行绘制,Mesh Filter组件里的Mesh属性就是我们这次主要操作的对象,在这里,我们用到:

  mesh.vertices数组 和 mesh.triangles数组,第一个是vector3的数组,第二个是int的数组。

  其中mesh.vertices存储的就是平面的顶点信息,对应上图就是0到6号这六个点的坐标。

  mesh.triangles存储的是平面绘制时,绘制三角形的顶点顺序,对应上图应该是:

  061 651 521 542 432(顺时针)

  每三个一组代表一个三角形,但是大家在这里要注意一下,就是最终绘制出的小三角形是单向图,就是一面可以看到,另一面是看不到的,所以,为了保证所有的小三角形朝向一至,要对mesh.triangles数组在进行调整,调整结果如下:

  016 156 125 245 234(逆时针)

  就是保证小三角形顶点都是按顺时针或者逆时针读取~大家想想就明白了~

  故:基本算法思想就是:

  入口参数:vector3[] vertices,储存平面定点信息,顶点需按顺序储存

  算法思想:从数组首尾向中间遍历,生成triangles顶点ID数组(下列代码中注释的部分)


 

步驟:

1、創建一個empty 的gameobject;

2、添加一個脚本給這個game object;

算法实现代码如下:

 

复制代码
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class quad : MonoBehaviour
{
    /*
    creat a triangle by using Mesh 
     2016/11/21
                 ————Carl    
    */
    void Start()
    {
        creatPolygon();
    }

   
    private void creatPolygon()
    {
        /* 1. 顶点,三角形,法线,uv坐标, 绝对必要的部分只有顶点和三角形。  
              如果模型中不需要场景中的光照,那么就不需要法线。如果模型不需要贴材质,那么就不需要UV */
        Vector3[] vertices =
        {
         new Vector3 (2f,0,0),
         new Vector3(4f, 0, 0),
         new Vector3(6f, 0, 0),
         new Vector3(10f, 0, 0),
         new Vector3(10f, 20f, 0),
         new Vector3(6f,10f, 0),
         new Vector3(4f, 4f, 0)
        
        };

        Vector3[] normals =
        {
            Vector3.up,
            Vector3.up,
            Vector3.up,
            Vector3.up,
            Vector3.up,
            Vector3.up,
            Vector3.up
           
        };

        Vector2[] uv =
        {
            Vector2.zero,
            -Vector2.left,
            Vector2.one,
            Vector2.right,
            Vector2.zero,
            -Vector2.left,
            Vector2.one
          
        };
        /*2. 三角形,顶点索引:  
         三角形是由3个整数确定的,各个整数就是角的顶点的index。 各个三角形的顶点的顺序通常由下往上数, 可以是顺时针也可以是逆时针,这通常取决于我们从哪个方向看三角形。 通常,当mesh渲染时,"逆时针" 的面会被挡掉。 我们希望保证顺时针的面与法线的主向一致 */
        int[] indices = new int[15];
        indices[0] = 0;
        indices[1] = 6;
        indices[2] = 1;

        indices[3] = 6;
        indices[4] = 2;
        indices[5] = 1;

        indices[6] =6;
        indices[7] = 5;
        indices[8] = 2;

        indices[9] = 5;
        indices[10] = 4;
        indices[11] = 2;

        indices[12] = 4;
        indices[13] = 3;
        indices[14] = 2;
        
       

        Mesh mesh = new Mesh();
            mesh.vertices = vertices;
            mesh.normals = normals;
            mesh.uv = uv;
            mesh.triangles = indices;

            MeshFilter meshfilter = this.gameObject.GetComponent<MeshFilter>();
            meshfilter.mesh = mesh;
        }

    }
复制代码

效果图:

 





教程二

// 通过object对象名 face 得到网格渲染器对象   
MeshFilter meshFilter = (MeshFilter)GameObject.Find( " face ").GetComponent( typeof(MeshFilter));  
          
// 通过渲染器对象得到网格对象   
Mesh mesh = meshFilter.mesh;  
      
// API中写的不是提清楚,我详细的在说一遍   
          
// 设置顶点,这个属性非常重要   
// 三个点确定一个面,所以Vector3数组的数量一定是3个倍数   
// 遵循顺时针三点确定一面   
// 这里的数量为6 也就是我创建了2个三角面   
// 依次填写3D坐标点   
mesh.vertices =  new Vector3[] { new Vector3( 500),  new Vector3( 050),  new Vector3( 005), new Vector3(- 500),  new Vector3( 0, - 50),  new Vector3( 00, - 5)};  
// mesh.vertices = new Vector3[] {new Vector3(5, 0, 0), new Vector3(0, 5, 0), new Vector3(0, 0, 5)};  
      
// 设置贴图点,因为面确定出来以后就是就是2D    
// 所以贴纸贴图数量为Vector2    
// 第一个三角形设置5个贴图   
// 第二个三角形设置一个贴图   
// 数值数量依然要和顶点的数量一样   
mesh.uv =  new Vector2[] { new Vector2( 00),  new Vector2( 05),  new Vector2( 55)};  
// mesh.uv = new Vector2[] {new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1)};
          
// 设置三角形索引,这个索引是根据上面顶点坐标数组的索引   
// 对应着定点数组Vector3中的每一项   
// 最后将两个三角形绘制在平面中   
// 数值数量依然要和顶点的数量一样   
mesh.triangles=  new  int []{ 0, 1, 2};  
复制代码

 
我测试时导入了一个立方体,测试时发现导入的立方体顶点是由4*6组成的,也就是说4个点组成一个面,立方体共6个面

顶点是由4*6组成的,但u3d还是会以三角网去解析,关键就是triangles,它负责存储每个三角网的顶点,也就是立方体的一个面由两个三角形组成

复制代码
MeshFilter meshFilter = (MeshFilter)GameObject.Find( " box ").GetComponent( typeof(MeshFilter));
Mesh mesh = meshFilter.mesh;
string strVertices =  "";
foreach(Vector3 v3  in mesh.vertices){
     if (strVertices== ""){
        strVertices = v3.ToString();
    }
     else{
        strVertices +=  " , " + v3.ToString();
    }
}
Debug.Log(mesh.vertices.Length +  "   " + strVertices);

string strUV =  "";
foreach(Vector2 v2  in mesh.uv){
     if (strUV== ""){
        strUV = v2.ToString();
    }
     else{
        strUV +=  " , " + v2.ToString();
    }
}
Debug.Log(mesh.uv.Length +  "   "+ strUV);
        
string strTriangles =  "";
foreach( int t  in mesh.triangles){
     if (strTriangles== ""){
        strTriangles = t.ToString();
    }
     else{
        strTriangles +=  " , " + t.ToString();
    }
}
Debug.Log(mesh.triangles.Length +  "   " + strTriangles);
复制代码

输出的信息如下:

(0.6, -0.6, 0.0),(-0.6, -0.6, 0.0),(0.6, 0.6, 0.0),(-0.6, 0.6, 0.0),
(0.6, -0.6, 0.7),(-0.6, -0.6, 0.7),(0.6, 0.6, 0.7),(-0.6, 0.6, 0.7),
(0.6, -0.6, 0.0),(-0.6, -0.6, 0.7),(-0.6, -0.6, 0.0),(0.6, -0.6, 0.7),
(-0.6, -0.6, 0.0),(-0.6, 0.6, 0.7),(-0.6, 0.6, 0.0),(-0.6, -0.6, 0.7),
(-0.6, 0.6, 0.0),(0.6, 0.6, 0.7),(0.6, 0.6, 0.0),(-0.6, 0.6, 0.7),
(0.6, 0.6, 0.0),(0.6, -0.6, 0.7),(0.6, -0.6, 0.0),(0.6, 0.6, 0.7)

(0.6, 0.1),(0.4, 0.1),(0.6, 0.4),(0.4, 0.4),
(0.4, 0.4),(0.6, 0.4),(0.4, 0.6),(0.6, 0.6),
(0.6, 0.4),(0.9, 0.6),(0.9, 0.4),(0.6, 0.6),
(0.3, 0.7),(0.6, 0.9),(0.6, 0.7),(0.3, 0.9),
(0.6, 0.7),(0.9, 0.9),(0.9, 0.7),(0.6, 0.9),
(0.1, 0.4),(0.3, 0.6),(0.3, 0.4),(0.1, 0.6)

2,0,3,
3,0,1,
5,4,7,
7,4,6,
10,8,9,
9,8,11,
14,12,13,
13,12,15,
18,16,17,
17,16,19,
22,20,21,
21,20,23


可以看出第一个平面是由0,1,2,3这四个点组成,在triangles中指定2,0,3这三个点绘制一个三角网,3,0,1这三个点绘制一个三角网。



猜你喜欢

转载自blog.csdn.net/zxy13826134783/article/details/80114487