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

結果如圖:



就是取得貼圖中的圓環部分。


五、總結

總得來說,平面圖形的貼圖還是比好好理解的,你也可以試試其他圖形的貼圖


最後給出所有貼圖的合照,哈哈



快過年了,新年快樂!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章