【Unity】メッシュをスクリプトで生成する

投稿者: | 2021-02-12

スクリプトで自由なサイズの直方体を生成してみました。

Meshクラスのオブジェクトのフィールドに、頂点や面、法線、UVなどの配列を入れて、メッシュフィルターコンポーネントに設定します。

頂点の配列の要素はローカル空間での位置です。面の配列には、三角形を構成する頂点の、頂点配列でのインデックスを入れます。

面の配列の要素数は3の倍数です。これは、3つごとに1つの三角面を定義するからです。面がこちらを向いているときに、時計回りの順番に設定するというルールがあります。

法線の配列では、同じインデックスの頂点の法線方向を設定するので、頂点の配列と要素数が同じになります。

参考:https://docs.unity3d.com/ja/2018.4/Manual/UsingtheMeshClass.html

直方体なので頂点数を8にすると、どうしても法線がうまく計算されませんでした。

本当は、四角面ごとに重複して頂点を作るそうです。参考:Unity:Mesh(メッシュ)の動的生成でキューブを生成

なので頂点数は3倍の24にしました。これは、Blenderで作ったCubeや、UnityのCubeをインスタンス化したものと同じです。

法線はMesh.RecalculateNormalsメソッドで自動で設定できます。

(修正済)using System.Collections;
using UnityEngine;

public class MeshTest : MonoBehaviour
{

    [SerializeField] float width;
    [SerializeField] float length;
    [SerializeField] float height;
    [SerializeField] Material material;

    // Start is called before the first frame update
    void Start()
    {

        // 頂点の配列
        var vertices = new Vector3[24];

        // 三角形の配列
        var tri = new int[36];

        // Y
        vertices[0] = new Vector3(-length / 2, height / 2, -width / 2);
        vertices[1] = new Vector3(-length / 2, height / 2, width / 2);
        vertices[2] = new Vector3(length / 2, height / 2, width / 2);
        vertices[3] = new Vector3(length / 2, height / 2, -width / 2);

        tri[0] = 0;
        tri[1] = 1;
        tri[2] = 2;

        tri[3] = 2;
        tri[4] = 3;
        tri[5] = 0;

        // -Y

        /*
        vertices[4] = new Vector3(-length / 2, -height / 2, -width / 2);
        vertices[5] = new Vector3(-length / 2, -height / 2, width / 2);
        vertices[6] = new Vector3(length / 2, -height / 2, width / 2);
        vertices[7] = new Vector3(length / 2, -height / 2, -width / 2);
        */

        vertices[4] = new Vector3(-length / 2, -height / 2, -width / 2);
        vertices[5] = new Vector3(length / 2, -height / 2, -width / 2);
        vertices[6] = new Vector3(length / 2, -height / 2, width / 2);
        vertices[7] = new Vector3(-length / 2, -height / 2, width / 2);

        tri[6] = 4;
        tri[7] = 5;
        tri[8] = 6;

        tri[9] = 6;
        tri[10] = 7;
        tri[11] = 4;

        // X
        vertices[8] = new Vector3(length / 2, height / 2, -width / 2);
        vertices[9] = new Vector3(length / 2, height / 2, width / 2);
        vertices[10] = new Vector3(length / 2, -height / 2, width / 2);
        vertices[11] = new Vector3(length / 2, -height / 2, -width / 2);

        tri[12] = 8;
        tri[13] = 9;
        tri[14] = 10;

        tri[15] = 10;
        tri[16] = 11;
        tri[17] = 8;

        // -X
        vertices[12] = new Vector3(-length / 2, height / 2, width / 2);
        vertices[13] = new Vector3(-length / 2, height / 2, -width / 2);
        vertices[14] = new Vector3(-length / 2, -height / 2, -width / 2);
        vertices[15] = new Vector3(-length / 2, -height / 2, width / 2);

        tri[18] = 12;
        tri[19] = 13;
        tri[20] = 14;

        tri[21] = 14;
        tri[22] = 15;
        tri[23] = 12;

        //Z
        vertices[16] = new Vector3(length / 2, height / 2, width / 2);
        vertices[17] = new Vector3(-length / 2, height / 2, width / 2);
        vertices[18] = new Vector3(-length / 2, -height / 2, width / 2);
        vertices[19] = new Vector3(length / 2, -height / 2, width / 2);

        tri[24] = 16;
        tri[25] = 17;
        tri[26] = 18;

        tri[27] = 18;
        tri[28] = 19;
        tri[29] = 16;

        // -Z
        vertices[20] = new Vector3(-length / 2, height / 2, -width / 2);
        vertices[21] = new Vector3(length / 2, height / 2, -width / 2);
        vertices[22] = new Vector3(length / 2, -height / 2, -width / 2);
        vertices[23] = new Vector3(-length / 2, -height / 2, -width / 2);

        tri[30] = 20;
        tri[31] = 21;
        tri[32] = 22;

        tri[33] = 22;
        tri[34] = 23;
        tri[35] = 20;

        // メッシュを新規作成
        Mesh mesh = new Mesh();

        // 頂点と面の配列を設定
        mesh.vertices = vertices;
        mesh.triangles = tri;

        // 法線を計算
        mesh.RecalculateNormals();

        // MeshFilterを付ける
        var mf = gameObject.AddComponent<MeshFilter>();

        // 作ったメッシュを設定
        mf.mesh = mesh;

        // MeshRendererを付ける
        var mr = gameObject.AddComponent<MeshRenderer>();

        // マテリアルを設定
        mr.material = material;

    }


}

サイズやマテリアルはインスペクタで設定します。

これで自由なサイズの直方体を作れました。

コメントを残す

メールアドレスが公開されることはありません。