UnityHexMap学习系列笔记之⼀⽤Mesh画⼀个正六边形前⾔
断断续续的在catlikecoding上学习,⼀路到了Hexmap系列,决定从此开始记录⼀下学习⼼得。也在⽹上看到了很多⼤⽜的翻译,⼤都是整篇整篇的翻译,⽽且纸上得来终觉浅,在此想把此系列教程,逐步分⼩篇幅边学习边记录学习过程中的⼼得
Hexmap系列最基础的开始就是画⼀个正六边形,因此作为系列学习⼊门,先从⽤Mesh画⼀个(仅仅是⼀个)正六边形说起
正六边形特性
如上图正六边形,有⼀下特性:
1. 六条边长都相等,设边长为L
2. 中⼼连接六个顶点,组成六个等边三⾓形
3. 外接圆(图中蓝⾊圆)半径,也就是outerRadius等于六边形边长。
4. 内切圆(图中红⾊虚线圆)半径,也就是innerRadius,根据简单的三⾓勾股定理求得等于.
正六边形顶点坐标
如图以正六边形顶点为原点,建⽴局部坐标系,因为最终六边形画在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),//V5unity 教程
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++)
{
, 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();
}
private void Triangulate()
{
//循环画出每⼀个三⾓形
for (int i = 0; i < 6; i++)
{
, 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);
}
}
最后运⾏得出⼀个正六边形
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论