[Unity] パスに沿った板(Plane)状のメッシュ生成

![スクリーンショット_20230223_182803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689374/86dc292d-f061-56a0-3604-48e81543f203.png)
板状のパスに沿ったメッシュ生成は投稿した記事のキューブ状のパスメッシュ生成のスクリプトに下側面だけ残すだけでほぼ出来ます。

https://qiita.com/okome184/items/c1e0b25d455ca6fd2ef0

``` c#:GeneratePathPlane.cs
using System.Collections.Generic;
using UnityEngine;

public class GeneratePathPlane : MonoBehaviour
{
    class Square
    {
        public Vector3 lowerLeft;
        public Vector3 upperLeft;
        public Vector3 lowerRight;
        public Vector3 upperRight;
    }

    [SerializeField] Transform[] PathPosition;
    [SerializeField] Material Material;
    [SerializeField] float Width = 1f;
    [SerializeField] bool IsDrawGizmo = false;


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

    private Square[] PathSquares()
    {
        int length = PathPosition.Length;
        var positions = new Vector3[length];
        var squares = new Square[length];

        for( int i = 0; i < length; i++)
        {
            positions[i] = PathPosition[i].position;
        }

        for (int i = 0; i < length; i++)
        {
            Vector3 firstPos, secondPos;

            if (i == 0)
            {
                firstPos = positions[0];
                secondPos = positions[1];
            }
            else
            {
                firstPos = positions[i - 1];
                secondPos = positions[i];
            }

            Vector3 direction = (secondPos - firstPos).normalized;
            Quaternion rot = Quaternion.LookRotation(direction);

            Vector3 lowerLeft = positions[i] + rot * Vector3.left * Width;
            Vector3 lowerRight = positions[i] + rot * Vector3.right * Width;

            var square = new Square()
            {
                lowerLeft = lowerLeft,
                lowerRight = lowerRight,
            };

            squares[i] = square;
        }

        return squares;
    }

    public void GenerateMesh()
    {
        var squares = PathSquares();
        var mesh = new Mesh();

        var vertices = new List<Vector3>();
        var triangles = new List<int>();
        var uvs = new List<Vector2>();

        for (int i = 0; i < squares.Length; i++)
        {
            vertices.Add(squares[i].lowerLeft);
            vertices.Add(squares[i].lowerRight);

            if (i % 2 == 0)
            {
                uvs.Add(new Vector2(0, 0));
                uvs.Add(new Vector2(1, 0));
            }
            else
            {
                uvs.Add(new Vector2(0, 1));
                uvs.Add(new Vector2(1, 1));
            }

            int currrentLowerLeft = (i * 2) + 0;
            int currrentLowerRight = (i * 2) + 1;

            if (i != 0)
            {
                int lastLowerLeft = ((i - 1) * 2) + 0;
                int lastLowerRight = ((i - 1) * 2) + 1;
                // 下側面
                //triangles.AddRange(SquareToTriangles(lastLowerRight, lastLowerLeft, currrentLowerRight, currrentLowerLeft));
                triangles.AddRange(SquareToTriangles(lastLowerLeft, lastLowerRight, currrentLowerLeft, currrentLowerRight));
            }
        }

        mesh.SetVertices(vertices);
        mesh.SetTriangles(triangles, 0);
        mesh.SetUVs(0, uvs);
        mesh.RecalculateNormals();

        var obj = new GameObject();
        obj.name = "GenerateMesh";
        obj.transform.parent = transform;
        var meshFilter = obj.AddComponent<MeshFilter>();
        var meshRenderer = obj.AddComponent<MeshRenderer>();
        var meshCollider = obj.AddComponent<MeshCollider>();

        meshFilter.mesh = mesh;
        meshCollider.sharedMesh = mesh;
        meshRenderer.material = Material;
    }

    private List<int> SquareToTriangles(int lowerLeft, int lowerRight, int upperLeft, int upperRight)
    {
        var triangles = new List<int>();

        triangles.Add(lowerLeft);   // 0
        triangles.Add(upperLeft);   // 2
        triangles.Add(lowerRight);  // 1

        triangles.Add(upperLeft);   // 2
        triangles.Add(upperRight);  // 3
        triangles.Add(lowerRight);  // 1

        return triangles;
    }

    private void OnDrawGizmos()
    {
        if((PathPosition == null) || (PathPosition.Length < 2) || !IsDrawGizmo)
        {
            return;
        }

        var squares = PathSquares();

        for (int i = 0; i < squares.Length; i++)
        {
            Gizmos.DrawSphere(squares[i].lowerLeft, 0.2f);
            Gizmos.DrawSphere(squares[i].lowerRight, 0.2f);
        }
    }
}

```