Unity Mesh Mesh 平面图形的贴图

Posted 御雪妃舞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Mesh Mesh 平面图形的贴图相关的知识,希望对你有一定的参考价值。

前面都讲了怎么画,没有写怎么贴图,上一篇提到了法线,今天这篇会说说平面图形的贴图。


我们完全按照第一篇Unity Mesh(一) 初步使用Mesh画平面图形的图形的顺序来进行贴图。


为了更好的观察,我们使用这张图片来进行贴图(可以右击保存):




一、三角形贴图

三角形的贴图是最简单的,因为我们画的三角形就简单,直接根据点来选取:


首先说下贴图的坐标系:如下图



然后看我们的三角形的坐标:



理论上,我们直接舍去三角形Vertices坐标的z就可以了,然后贴图就应该是图中的黄色三角形内的区域,下面我们验证下:


代码如下:

void DrawTriangle()
    
        gameObject.AddComponent<MeshFilter>();
        gameObject.AddComponent<MeshRenderer>();
        gameObject.GetComponent<MeshRenderer>().material = mat;

        Mesh mesh = GetComponent<MeshFilter>().mesh;
        mesh.Clear();

        //设置顶点
        mesh.vertices = new Vector3[]  new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0) ;
        mesh.uv = new Vector2[]  new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) ;

        mesh.triangles = new int[]  0, 1, 2 ;
    

结果如图:



可以看到和我们预想的一样。


二、正方形贴图

正方形的贴图就比较简单了,直接是整张图片,就是把画正方形的四个点的z值舍去变成二维坐标就可以了。


代码如下:


void DrawSquare()
    
        gameObject.AddComponent<MeshFilter>();
        gameObject.AddComponent<MeshRenderer>();
        gameObject.GetComponent<MeshRenderer>().material = mat;

        Mesh mesh = GetComponent<MeshFilter>().mesh;
        mesh.Clear();

        mesh.vertices = new Vector3[]  new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0) ;
        mesh.triangles = new int[]
         0, 1, 2,
          0, 2, 3
        ;
        mesh.uv = new Vector2[]  new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) ;
    

结果如图:



三、圆的贴图


圆的贴图,稍微复杂一点,涉及到坐标轴的转换,我们先说下逻辑思路:


从图片的讲解中就可以看到我们队x,y的处理,就是我们脚本中需要对我们的坐标进行的处理,好了代码如下:
#region 画圆
    /// <summary>
    /// 画圆
    /// </summary>
    /// <param name="radius">圆的半径</param>
    /// <param name="segments">圆的分割数</param>
    /// <param name="centerCircle">圆心得位置</param>
    void DrawCircle(float radius, int segments, Vector3 centerCircle)
    
        gameObject.AddComponent<MeshFilter>();
        gameObject.AddComponent<MeshRenderer>();
        gameObject.GetComponent<MeshRenderer>().material = mat;

        //顶点
        Vector3[] vertices = new Vector3[segments + 1];
        vertices[0] = centerCircle;
        float deltaAngle = Mathf.Deg2Rad * 360f / segments;
        float currentAngle = 0;
        for (int i = 1; i < vertices.Length; i++)
        
            float cosA = Mathf.Cos(currentAngle);
            float sinA = Mathf.Sin(currentAngle);
            vertices[i] = new Vector3(cosA * radius + centerCircle.x, sinA * radius + centerCircle.y, 0);
            currentAngle += deltaAngle;
        

        //三角形
        int[] triangles = new int[segments * 3];
        for (int i = 0, j = 1; i < segments * 3 - 3; i += 3, j++)
        
            triangles[i] = 0;
            triangles[i + 1] = j + 1;
            triangles[i + 2] = j;
        
        triangles[segments * 3 - 3] = 0;
        triangles[segments * 3 - 2] = 1;
        triangles[segments * 3 - 1] = segments;

        Vector2[] uvs = new Vector2[vertices.Length];
        for (int i = 0; i < vertices.Length; i++)
        
            uvs[i] = new Vector2(vertices[i].x / radius / 2 + 0.5f, vertices[i].y / radius / 2 + 0.5f);
        


        Mesh mesh = GetComponent<MeshFilter>().mesh;
        mesh.Clear();

        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;
    
    #endregion

结果如图:


是不是跟我们预想的一样,哈哈。

四、圆环的贴图

圆环的做法和圆的贴图取法是一样的:


不过我们需要取的半径是内圆的半径,不然就会重复贴图了。


代码如下:


 #region 画圆环
    /// <summary>
    /// 画圆环
    /// </summary>
    /// <param name="radius">圆半径</param>
    /// <param name="innerRadius">内圆半径</param>
    /// <param name="segments">圆的分个数</param>
    /// <param name="centerCircle">圆心坐标</param>
    void DrawRing(float radius, float innerRadius, int segments, Vector3 centerCircle)
    
        gameObject.AddComponent<MeshFilter>();
        gameObject.AddComponent<MeshRenderer>();
        gameObject.GetComponent<MeshRenderer>().material = mat;

        //顶点
        Vector3[] vertices = new Vector3[segments * 2];
        float deltaAngle = Mathf.Deg2Rad * 360f / segments;
        float currentAngle = 0;
        for (int i = 0; i < vertices.Length; i += 2)
        
            float cosA = Mathf.Cos(currentAngle);
            float sinA = Mathf.Sin(currentAngle);
            vertices[i] = new Vector3(cosA * innerRadius + centerCircle.x, sinA * innerRadius + centerCircle.y, 0);
            vertices[i + 1] = new Vector3(cosA * radius + centerCircle.x, sinA * radius + centerCircle.y, 0);
            currentAngle += deltaAngle;
        

        //三角形
        int[] triangles = new int[segments * 6];
        for (int i = 0, j = 0; i < segments * 6; i += 6, j += 2)
        
            triangles[i] = j;
            triangles[i + 1] = (j + 1) % vertices.Length;
            triangles[i + 2] = (j + 3) % vertices.Length;

            triangles[i + 3] = j;
            triangles[i + 4] = (j + 3) % vertices.Length;
            triangles[i + 5] = (j + 2) % vertices.Length;
        

        Vector2[] uvs = new Vector2[vertices.Length];
        for (int i = 0; i < vertices.Length; i++)
        
            uvs[i] = new Vector2(vertices[i].x / innerRadius / 2 + 0.5f, vertices[i].y / innerRadius / 2 + 0.5f);
        

        Mesh mesh = GetComponent<MeshFilter>().mesh;
        mesh.Clear();

        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;

    
    #endregion

结果如图:



就是取得贴图中的圆环部分。


五、总结

总得来说,平面图形的贴图还是比好好理解的,你也可以试试其他图形的贴图


最后给出所有贴图的合照,哈哈



快过年了,新年快乐!

以上是关于Unity Mesh Mesh 平面图形的贴图的主要内容,如果未能解决你的问题,请参考以下文章

unity中mesh属性的uv坐标讨论

Unity Mesh Mesh 正八面体Octaheron贴图

Unity Mesh Mesh 立方体Cube贴图以及六个面分别贴不同的图片

Unity场景优化工具:Mesh Baker 基础教程(贴图篇)

Unity中的Mesh网格编程——绘制基本2D图形

Unity中的Mesh网格编程——绘制基本2D图形