Unity HexMap学习系列笔记之一用Mesh画一个正六边形

前言

断断续续的在catlikecoding.com上学习,一路到了Hexmap系列,决定从此开始记录一下学习心得。也在网上看到了很多大牛的翻译,大都是整篇整篇的翻译,而且纸上得来终觉浅,在此想把此系列教程,逐步分小篇幅边学习边记录学习过程中的心得

Hexmap系列最基础的开始就是画一个正六边形,因此作为系列学习入门,先从用Mesh画一个(仅仅是一个)正六边形说起

正六边形特性

 

如上图正六边形,有一下特性:

  1. 六条边长都相等,设边长为L
  2. 中心连接六个顶点,组成六个等边三角形
  3. 外接圆(图中蓝色圆)半径,也就是outerRadius等于六边形边长L
  4. 内切圆(图中红色虚线圆)半径,也就是innerRadius,根据简单的三角勾股定理求得等于(\sqrt{3}L)/2.

正六边形顶点坐标

如图以正六边形顶点为原点,建立局部坐标系,因为最终六边形画在XZ平面,所以红色对应为unityX轴,蓝色为Z轴。Y轴坐标为0。坐标轴原点为V0,六个顶点顺时针分别命名为V1,V2,V3,V4,V5,V6。

则在此坐标系下,根据简单的计算(也就是直角三角形勾股定理这些)可以计算出每个顶点的坐标,如下:

 //正六边形外接圆半径,等于正六边形边长
    public const float outerRadius = 20;
    //正六边形内切圆半径,等于sqrt(3)*outerRaidus/2,其中sqrt(3)/2 = 0.866025404f
    public const float innerRadius = outerRadius * 0.866025404f;
  
    private   Vector3[] corners = 
    {
        new Vector3(0,0,outerRadius),//V1
        new Vector3(innerRadius,0,0.5f*outerRadius),//V2
        new Vector3(innerRadius,0,-0.5f*outerRadius),//V3
        new Vector3(0,0,-outerRadius),//V4
        new Vector3(-innerRadius,0,-0.5f*outerRadius),//V5
        new Vector3(-innerRadius,0,0.5f*outerRadius),//V6
        
    };

 

开始画一个正六边形

创建一个MonoBehaviour脚本,命名为Hexgon,定义Mesh变量,和mesh需要的顶点和三角形数据信息

    Mesh HexagonMesh;
    private List<Vector3> vertices = new List<Vector3>();
    private List<int> triangles = new List<int>();

在Awake里完成相关初始化

private void Awake()
 {
       
        GameObject MeshSpwan = new GameObject("MeshSpwan");
        MeshSpwan.AddComponent<MeshFilter>();
        MeshSpwan.AddComponent<MeshRenderer>();

        HexagonMesh = MeshSpwan.GetComponent<MeshFilter>().mesh;
        HexagonMesh.Clear();
        
      

 }

对于自定义Mesh,如果想要画出想要的图形,需要计算出该mesh的顶点数据(也就是mesh里面的vertices数据)和mesh中对应的三角形数据(也就是顶点索引)

private void Triangulate()
    {
        //循环画出每一个三角形
       
        for (int i = 0; i < 6; i++)
        {
            AddRriangle(Vector3.zero, corners[i], corners[i + 1]);
        }
    }
    private void AddRriangle(Vector3 v1,Vector3 v2,Vector3 v3)
    {
        int verterIndex = vertices.Count;
        //三角形1顶点数据(V0,V1,V2)
        //三角形2顶点数据(V0,V2,V3)
        //三角形3顶点数据(V0,V3,V4)
        //三角形4顶点数据(V0,V4,V5)
        //三角形5顶点数据(V0,V5,V6)
        //三角形3顶点数据(V0,V6,V1)
        vertices.Add(v1);
        vertices.Add(v2);
        vertices.Add(v3);
        //第一个三角形对应的triangles索引在verterices的索引是(0,1,2)
        //第而个三角形对应的triangles索引在verterices的索引是(3,4,5)
        ///...
        triangles.Add(verterIndex);
        triangles.Add(verterIndex + 1);
        triangles.Add(verterIndex + 2);
    }

最终代码为

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

public class Hexagon : MonoBehaviour
{
    Mesh HexagonMesh;
    private List<Vector3> vertices = new List<Vector3>();
    private List<int> triangles = new List<int>();
    //正六边形外接圆半径,等于正六边形边长
    public const float outerRadius = 20;
    //正六边形内切圆半径,等于sqrt(3)*outerRaidus/2,其中sqrt(3)/2 = 0.866025404f
    public const float innerRadius = outerRadius * 0.866025404f;
  
    private   Vector3[] corners = 
    {
        new Vector3(0,0,outerRadius),//V1
        new Vector3(innerRadius,0,0.5f*outerRadius),//V2
        new Vector3(innerRadius,0,-0.5f*outerRadius),//V3
        new Vector3(0,0,-outerRadius),//V4
        new Vector3(-innerRadius,0,-0.5f*outerRadius),//V5
        new Vector3(-innerRadius,0,0.5f*outerRadius),//V6
        new Vector3(0,0,outerRadius),//V1。形成一个闭环,组织mesh三角形数据的时候需要
        
    };
    private void Awake()
    {
       
        GameObject MeshSpwan = new GameObject("MeshSpwan");
        MeshSpwan.AddComponent<MeshFilter>();
        MeshSpwan.AddComponent<MeshRenderer>();

        HexagonMesh = MeshSpwan.GetComponent<MeshFilter>().mesh;
        HexagonMesh.Clear();
        
      

    }
    private void Start()
    {
        Triangulate();

        HexagonMesh.vertices = vertices.ToArray();
        HexagonMesh.triangles = triangles.ToArray();
    }

    private void Triangulate()
    {
        //循环画出每一个三角形
       
        for (int i = 0; i < 6; i++)
        {
            AddRriangle(Vector3.zero, corners[i], corners[i + 1]);
        }
    }
    private void AddRriangle(Vector3 v1,Vector3 v2,Vector3 v3)
    {
        int verterIndex = vertices.Count;
        //三角形1顶点数据(V0,V1,V2)
        //三角形2顶点数据(V0,V2,V3)
        //三角形3顶点数据(V0,V3,V4)
        //三角形4顶点数据(V0,V4,V5)
        //三角形5顶点数据(V0,V5,V6)
        //三角形3顶点数据(V0,V6,V1)
        vertices.Add(v1);
        vertices.Add(v2);
        vertices.Add(v3);
        //第一个三角形对应的triangles索引在verterices的索引是(0,1,2)
        //第而个三角形对应的triangles索引在verterices的索引是(3,4,5)
        ///...
        triangles.Add(verterIndex);
        triangles.Add(verterIndex + 1);
        triangles.Add(verterIndex + 2);
    }


}

最后运行得出一个正六边形

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值