meshを利用して2D図形を簡単に作成【Unityメモ】

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の値を増やすと、下記のように多角形が作成できます。

タイトルとURLをコピーしました