UnityのMeshを利用して、スクリプトで図形(三角形や四角形など)を作成してみます。
はじめに
Unityのバージョンは2021.3.14f1です。
下記では、LineRendererを利用して簡単に図形を作成しています。
今回は、Meshを利用して同じように図形を作成してみます。
実装開始
Meshについて簡単に確認してからスクリプトで図形を作成してみます。
オブジェクトの作成
「CreateEmpty」で空のオブジェクトを追加します。
「AddComponent」から「MeshRenderer」と「MeshFilter」を追加。
試しにMeshFilterを変更してみます。
Sceneの表示をWireframeにすると、下記のように図形のメッシュが表示されます。
メッシュは頂点と複数の三角形で構成されています。詳しくは下記公式リファレンス
スクリプトで固定図形を作成
Meshの基本となる三角形を作成してみます。
下記スクリプトを作成してオブジェクトにアタッチします。
using UnityEngine; public class DrawShape : MonoBehaviour { private Mesh _mesh; private Vector3[] _vertices; void Start() { _mesh = GetComponent<MeshFilter>().mesh; _vertices = new Vector3[3]; _vertices[0] = new Vector3(0, 0); _vertices[1] = new Vector3(0, 1); _vertices[2] = new Vector3(1, 1); int[] _triangles = { 0, 1, 2 }; _mesh.Clear(); _mesh.vertices = _vertices; _mesh.triangles = _triangles; } }
_verticesで頂点の座標をセット、_trianglesで三角形の配列を指定しています。
実行すると、下記のようになります。0→1→2の順番で三角形の外線を作成し、中を塗りつぶしています。
四角形の場合は下記のように、頂点座標を4つ用意して(0,1,2,3)、三角形を2つ作成します(0→1→2),(0→2→3)。
スクリプトにすると下記のようになります。
using UnityEngine; public class DrawShape : MonoBehaviour { private Mesh _mesh; private Vector3[] _vertices; private int[] _triangles; void Start() { _mesh = GetComponent<MeshFilter>().mesh; _vertices = GetVerticesPoints().ToArray(); _triangles = GetTriangles(); _mesh.Clear(); _mesh.vertices = _vertices; _mesh.triangles = _triangles; } private List<Vector3> GetVerticesPoints() { List<Vector3> points = new List<Vector3>(); points.Add(new Vector3(0, 0)); points.Add(new Vector3(0, 1)); points.Add(new Vector3(1, 1)); points.Add(new Vector3(1, 0)); return points; } private int[] GetTriangles() { List<int> triangles = new List<int>(); triangles.Add(0); triangles.Add(1); triangles.Add(2); triangles.Add(0); triangles.Add(2); triangles.Add(3); return triangles.ToArray(); } }
多角形をスクリプトで作成
次に、LineRendererの時と同様に変則多角形を作成してみます。
内接するn角形の座標
半径rの円があり、その円に内接するn角形の座標は下記のように求めることが出来ます(i=0,1,2,…,n-1)。
この式を利用すると、下記のように頂点の座標を求めることができます。半径rは1なので省略。
private List<Vector3> GetVerticesPoints() { private int VNum = 4; List<Vector3> points = new List<Vector3>(); float step = 2.0f * Mathf.PI / (float)VNum; float x, y; for (int i = 0; i < VNum; i++) { x = Mathf.Cos(i * step); y = Mathf.Sin(i * step); points.Add(new Vector3(x, y, 0)); } return points; }
四角形の場合は下記のようにtrianglesを指定します。
private int[] GetTriangles() { List<int> triangles = new List<int>(); triangles.Add(0); triangles.Add(2); triangles.Add(1); triangles.Add(0); triangles.Add(3); triangles.Add(2); return triangles.ToArray(); }
最終スクリプト
最終的にスクリプトは下記のようになります。
using UnityEngine; public class DrawShape : MonoBehaviour { [SerializeField] private int VNum; private Mesh _mesh; private Vector3[] _vertices; private int[] _triangles; void Start() { _mesh = GetComponent<MeshFilter>().mesh; } private void Update() { _vertices = GetVerticesPoints().ToArray(); _triangles = GetTriangles(); _mesh.Clear(); _mesh.vertices = _vertices; _mesh.triangles = _triangles; } private List<Vector3> GetVerticesPoints() { List<Vector3> points = new List<Vector3>(); float step = 2.0f * Mathf.PI / (float)VNum; float x, y; for (int i = 0; i < VNum; i++) { x = Mathf.Cos(i * step); y = Mathf.Sin(i * step); points.Add(new Vector3(x, y, 0)); } return points; } private int[] GetTriangles() { List<int> triangles = new List<int>(); for (int i = 0; i < _vertices.Length - 2; i++) { triangles.Add(0); triangles.Add(i+2); triangles.Add(i+1); } return triangles.ToArray(); } }
実行してVNumの値を増やすと、下記のように多角形が作成できます。