本文基于 Unity 自定义 mesh 绘制 一文,在修改 mesh 的基础上,进一步实现 tile map。

第一步:修改 mesh 顶点与三角片信息,生成方格

顶点信息由一系列正方形组合而成。三角片的实现方式是:一个矩形由 2 个三角形组成。注意,三角形的顶点顺序决定了面的朝向——三个顶点按观察方向顺时针排列。三角形数量 = 顶点数量 × 6(6 = 2 个三角形 × 3 个顶点)。传入的三角数组中,每个值对应顶点数组中对应顶点的 index。代码如下:

using UnityEngine;
using System.Collections;


public class ss5 : MonoBehaviour
{
    void Start()
    {
        dooo();

    }

    void dooo()
    {
        {

            MeshFilter filter = this.GetComponent<MeshFilter>();
            MeshRenderer render = this.GetComponent<MeshRenderer>();
            var mesh = filter.mesh;

            var ts = this.GetComponentsInChildren<Transform>();

            Vector3[] vers = new Vector3[ts.Length];

            for (int i = 0; i < ts.Length; i++)
            {
                vers[i] = ts[i].position;
            }

            const int MAX_X = 30;
            const int MAX_Y = 30;
            Vector3[] vertics = new Vector3[MAX_Y * MAX_X];

            for (int x = 0; x < MAX_X; x++)
            {
                for (int y = 0; y < MAX_Y; y++)
                {
                    vertics[x + MAX_X * y] = new Vector3(x, 0f, y);
                }
            }
            foreach (var p in vertics)
            {
                Ray ray = new Ray(p, new Vector3(-100f, -100f, -100f));
                Debug.DrawLine(ray.GetPoint(-0.1f), ray.GetPoint(0.1f), Color.red);
            }
            int[] triss = new int[(MAX_Y - 1) * (MAX_X - 1) * 6];

            for (int x = 0; x < MAX_X - 1; x++)
            {
                for (int y = 0; y < MAX_Y - 1; y++)
                {
                    var p = vertics[x + MAX_X * y];
                    int baseIdx = 0;
                    if (y >= 1)
                    {
                        baseIdx = (y * (MAX_X - 1) * 6) + x * 6;
                    }
                    else
                    {
                        baseIdx = x * 6;
                    }
                    Debug.LogError(x + "   " + y + "    " + triss.Length + "  baseIdx=" + baseIdx);
                    triss[baseIdx + 0] = x + y * MAX_X;
                    triss[baseIdx + 1] = x + (y + 1) * MAX_X;
                    triss[baseIdx + 2] = (x + 1) + y * MAX_X;
                    triss[baseIdx + 3] = x + (y + 1) * MAX_X;
                    triss[baseIdx + 4] = (x + 1) + (y + 1) * MAX_X;
                    triss[baseIdx + 5] = (x + 1) + y * MAX_X; ;

                    /*   triss[x + y * MAX_X + 0] = 0;
                    triss[x + y * MAX_X + 1] = 2;
                    triss[x + y * MAX_X + 2] = 1;
                    triss[x + y * MAX_X + 3] = 2;
                    triss[x + y * MAX_X + 4] = 3;
                    triss[x + y * MAX_X + 5] = 1;
    */

                    /* triss[(x * 2 + y * 9 * 2) + 0] = 5;
                     triss[(x * 2 + y * 9 * 2) + 1] = 5;
                     triss[(x * 2 + y * 9 * 2) + 2] = 5;
                     triss[(x * 2 + y * 9 * 2) + 3] = 5;
                     triss[(x * 2 + y * 9 * 2) + 4] = 5;
                     triss[(x * 2 + y * 9 * 2) + 5] = 5;
                     */
                }
            }


            mesh.vertices = vertics;
            mesh.triangles = triss;// this.GetTris(vers);
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
            this.GetComponent<MeshCollider>().sharedMesh = mesh;
            filter.mesh = mesh;
            return;
        }
    }
    void Update()
    {

    }



    void OnDrawGizmos()
    {
        return;

        {

            MeshFilter filter = this.GetComponent<MeshFilter>();
            MeshRenderer render = this.GetComponent<MeshRenderer>();
            var mesh = filter.mesh;

            var ts = this.GetComponentsInChildren<Transform>();

            Vector3[] vers = new Vector3[ts.Length];

            for (int i = 0; i < ts.Length; i++)
            {
                vers[i] = ts[i].position;
            }

            const int MAX_X = 3;
            const int MAX_Y = 3;
            Vector3[] vertics = new Vector3[MAX_Y * MAX_X];

            for (int x = 0; x < MAX_X; x++)
            {
                for (int y = 0; y < MAX_Y; y++)
                {
                    vertics[x + MAX_X * y] = new Vector3(x, 0f, y);
                }
            }
            foreach (var p in vertics)
            {
                Ray ray = new Ray(p, new Vector3(-100f, -100f, -100f));
                Debug.DrawLine(ray.GetPoint(-0.1f), ray.GetPoint(0.1f), Color.red);
            }
            int[] triss = new int[(MAX_Y - 1) * (MAX_X - 1) * 6];

            for (int x = 0; x < MAX_X - 1; x++)
            {
                for (int y = 0; y < MAX_Y - 1; y++)
                {
                    var p = vertics[x + MAX_X * y];
                    int baseIdx = 0;
                    if (y >= 1)
                    {
                        baseIdx = (y * (MAX_X - 1) * 6) + x * 6;
                    }
                    else
                    {
                        baseIdx = x * 6;
                    }
                    Debug.LogError(x + "   " + y + "    " + triss.Length + "  baseIdx=" + baseIdx);
                    triss[baseIdx + 0] = x + y * MAX_X;
                    triss[baseIdx + 1] = x + (y + 1) * MAX_X;
                    triss[baseIdx + 2] = (x + 1) + y * MAX_X;
                    triss[baseIdx + 3] = x + (y + 1) * MAX_X;
                    triss[baseIdx + 4] = (x + 1) + (y + 1) * MAX_X;
                    triss[baseIdx + 5] = (x + 1) + y * MAX_X; ;

                    /*   triss[x + y * MAX_X + 0] = 0;
                    triss[x + y * MAX_X + 1] = 2;
                    triss[x + y * MAX_X + 2] = 1;
                    triss[x + y * MAX_X + 3] = 2;
                    triss[x + y * MAX_X + 4] = 3;
                    triss[x + y * MAX_X + 5] = 1;
    */
                    /* triss[(x * 2 + y * 9 * 2) + 0] = 5;
                     triss[(x * 2 + y * 9 * 2) + 1] = 5;
                     triss[(x * 2 + y * 9 * 2) + 2] = 5;
                     triss[(x * 2 + y * 9 * 2) + 3] = 5;
                     triss[(x * 2 + y * 9 * 2) + 4] = 5;
                     triss[(x * 2 + y * 9 * 2) + 5] = 5;
                     */
                }
            }


            mesh.vertices = vertics;
            mesh.triangles = triss;// this.GetTris(vers);
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
            this.GetComponent<MeshCollider>().sharedMesh = mesh;
            filter.mesh = mesh;
            return;
        }
    }


}

第二步:修改 UV 信息实现 tile map

U 对应 x 轴,V 对应 y 轴。矩形的 4 个顶点对应 UV 坐标的 4 个点,此处顶点顺序为逆时针,UV 坐标同样按逆时针排列。因此只需要一张大贴图,配合对应的 UV 信息,即可实现 tile map。