动态创建六角格网格

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HexMap : MonoBehaviour
{
    public int RowCount = 300;
    public int ColumnCount = 350;
    public Material Mat;
    private Map map;
    // Start is called before the first frame update
    void Start()
    {
        GenerateHexData();
    }

    /// <summary>
    /// 点击生成网格
    /// </summary>
    public void OnClickGenerateMesh()
    {
        float time = Time.realtimeSinceStartup;
        GenerateMapMesh();
        Debug.LogError("网格生成完成 " + (Time.realtimeSinceStartup - time));
    }

    private void OnDrawGizmos()
    {

    }

    private void GenerateHexData()
    {
        map = new Map(RowCount, ColumnCount, 10f);
    }

    private void GenerateMapMesh()
    {
        List<List<Hexagon>> allHexs = new List<List<Hexagon>>();
        List<Hexagon> hexList = new List<Hexagon>();
        foreach (var row in map.hexagonDict)
        {
            foreach (var hex in row.Value)
            {
                hexList.Add(hex.Value);
                if (hexList.Count > 10000)
                {
                    allHexs.Add(hexList);
                    hexList = new List<Hexagon>();
                }
            }
        }
        allHexs.Add(hexList);
        for (int j = 0; j < allHexs.Count; j++)
        {
            GameObject obj = new GameObject("MapHex" + j);
            obj.transform.SetParent(transform);
            MeshRenderer meshRender = obj.AddComponent<MeshRenderer>();
            meshRender.sharedMaterial = Mat;
            MeshFilter filter = obj.AddComponent<MeshFilter>();
            hexList = allHexs[j];
            Vector3[] vertices = new Vector3[hexList.Count * 6];
            int[] triangles = new int[hexList.Count * 12];
            Vector2[] uvs = new Vector2[vertices.Length];
            for (int i = 0; i < hexList.Count; i++)
            {
                Hexagon hex = hexList[i];
                vertices[i * 6] = hex.Left;
                vertices[i * 6 + 1] = hex.TopLeft;
                vertices[i * 6 + 2] = hex.TopRight;
                vertices[i * 6 + 3] = hex.Right;
                vertices[i * 6 + 4] = hex.BottomRight;
                vertices[i * 6 + 5] = hex.BottomLeft;
                uvs[i * 6] = new Vector2(0, 0.5f);
                uvs[i * 6 + 1] = new Vector2(0.25f, 1f);
                uvs[i * 6 + 2] = new Vector2(0.75f, 1f);
                uvs[i * 6 + 3] = new Vector2(1, 0.5f);
                uvs[i * 6 + 4] = new Vector2(0.75f, 0f);
                uvs[i * 6 + 5] = new Vector2(0.25f, 0f);
                triangles[i * 12] = i * 6;
                triangles[i * 12 + 1] = i * 6 + 1;
                triangles[i * 12 + 2] = i * 6 + 5;
                triangles[i * 12 + 3] = i * 6 + 1;
                triangles[i * 12 + 4] = i * 6 + 2;
                triangles[i * 12 + 5] = i * 6 + 5;
                triangles[i * 12 + 6] = i * 6 + 2;
                triangles[i * 12 + 7] = i * 6 + 3;
                triangles[i * 12 + 8] = i * 6 + 5;
                triangles[i * 12 + 9] = i * 6 + 3;
                triangles[i * 12 + 10] = i * 6 + 4;
                triangles[i * 12 + 11] = i * 6 + 5;
            }

            Mesh mesh = new Mesh();
            mesh.vertices = vertices;
            mesh.triangles = triangles;
            mesh.uv = uvs;
            mesh.RecalculateNormals();
            filter.mesh = mesh;
        }

    }
}

public class Map
{
    public float FaceSideDis;
    public float FaceVertexDis;
    public int RowCount;
    public int ColCount;
    public Dictionary<int, Dictionary<int, Hexagon>> hexagonDict = new Dictionary<int, Dictionary<int, Hexagon>>();

    public Map(int r, int c, float sideDis)
    {
        FaceSideDis = sideDis;
        FaceVertexDis = sideDis / Mathf.Sin(60 * Mathf.Deg2Rad);
        RowCount = r;
        ColCount = c;
        float time = Time.realtimeSinceStartup;
        GenerateMap();
        Debug.LogError("GenerateMap Over" + (Time.realtimeSinceStartup - time));
    }

    public void GenerateMap()
    {
        float halfFaceSideDis = FaceSideDis / 2;
        float halfFaceVertexDis = FaceVertexDis / 2;
        float xGap = 0.75f * FaceVertexDis;
        for (int r = 0; r < RowCount; r++)
        {
            float evenCenterY = FaceSideDis * r + FaceSideDis;
            float eventTopY = evenCenterY + halfFaceSideDis;
            float eventBottomY = evenCenterY - halfFaceSideDis;
            float oddCenterY = halfFaceSideDis + FaceSideDis * r;
            float oddTopY = oddCenterY + halfFaceSideDis;
            float oddBottomY = oddCenterY - halfFaceSideDis;
            for (int c = 0; c < ColCount; c++)
            {
                bool isOdd = c % 2 == 1;
                Hexagon hex = new Hexagon(r, c);
                if (!hexagonDict.ContainsKey(r))
                {
                    hexagonDict.Add(r, new Dictionary<int, Hexagon>());
                }
                hexagonDict[r][c] = hex;
                hex.Center = Vector3.zero;
                hex.Center.x = xGap * c + halfFaceVertexDis;
                hex.Center.z = isOdd ? oddCenterY : evenCenterY;
                Vector3 left = Vector3.zero;
                if (c == 0)
                {
                    left.x = 0;
                    left.z = hex.Center.z;
                }
                else
                {
                    left = isOdd ? hexagonDict[r][c - 1].BottomRight : hexagonDict[r][c - 1].TopRight;
                }
                hex.Left = left;
                Vector3 topLeft = Vector3.zero;
                if (isOdd)
                {
                    topLeft = hexagonDict[r][c - 1].Right;
                }
                else
                {
                    topLeft.x = (hex.Center.x + left.x) / 2;
                    topLeft.z = hex.Center.z + halfFaceSideDis;
                }
                hex.TopLeft = topLeft;
                Vector3 right = Vector3.zero;
                if (isOdd && r > 0 && c < ColCount - 1)
                {
                    right = hexagonDict[r - 1][c + 1].TopLeft;
                }
                else
                {
                    right.x = left.x + FaceVertexDis;
                    right.z = hex.Center.z;
                }
                hex.Right = right;
                Vector3 topRight = Vector3.zero;
                topRight.x = (hex.Center.x + right.x) / 2;
                topRight.z = hex.Center.z + halfFaceSideDis;
                hex.TopRight = topRight;
                Vector3 bottomRight = Vector3.zero;
                if (r > 0)
                {
                    bottomRight = hexagonDict[r - 1][c].TopRight;
                }
                else
                {
                    bottomRight.x = (topRight.x);
                    bottomRight.z = hex.Center.z - halfFaceSideDis;
                }
                hex.BottomRight = bottomRight;
                Vector3 bottomLeft = Vector3.zero;
                if (r > 0)
                {
                    bottomLeft = hexagonDict[r - 1][c].TopLeft;
                }
                else if (!isOdd && c > 0)
                {
                    bottomLeft = hexagonDict[r][c - 1].Right;
                }
                else
                {
                    bottomLeft.x = (topLeft.x);
                    bottomLeft.z = hex.Center.z - halfFaceSideDis;
                }
                hex.BottomLeft = bottomLeft;
            }

        }
    }
}

public class Hexagon
{
    public int Row;
    public int Col;
    public Hexagon(int row, int col)
    {
        Row = row;
        Col = col;
    }
    public Vector3 Center;
    public Vector3 Left;
    public Vector3 TopLeft;
    public Vector3 TopRight;
    public Vector3 Right;
    public Vector3 BottomRight;
    public Vector3 BottomLeft;


}

速度不慢,Drawcall少,或者还可以通过设置顶点颜色来更改颜色。

注意的点:

顶点数量太多的话无法创建,需要分成多个物体来渲染。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值