UNITY3D 단순 2D 다각형 노면 그리기

5274 단어 UNITY3d
소개: 새 프로젝트에서 무한 순환이 가능한 2D 다각형 도로를 그려야 하기 때문에 2D 다각형 생성기를 썼습니다.Mesh 그리기, 차단 및 도로 묘사 3개 부분을 포함하여 코드는 다음과 같습니다.
using UnityEngine;

public class PolyMesh2D : MonoBehaviour
{
    public Vector2[] toppoints { get; set; }
    public Vector2[] botpoints {get;set;}
    public Vector2[] roundpoints { get;set;}
    public Vector2 lastpoint
    {
        get
        {
            return toppoints[toppoints.Length - 1] + transform.position.IgnoreZAxis();
        }
    }
    public Vector3[] mvertices { get; set; }
    public int[] mtriangles { get; set; }
    public float wide
    {
        get
        {
            return lastpoint.x - toppoints[0].x;
        }
    }
    public int vectnum;
    public Color matcolor;
    
    public enum OutlingType
    {
        up,down,all,
    }
    private MeshFilter meshFilter;
    private MeshRenderer meshrender;
    private Mesh mesh;
    private LineRenderer myline;

    //     
    public void DefaultSet(int vectnum, Color matcolor)
    {
        this.vectnum = vectnum;
        this.matcolor = matcolor;
        toppoints = new Vector2[vectnum];
        botpoints = new Vector2[vectnum];
        roundpoints = new Vector2[vectnum * 2 + 1];
        mvertices = new Vector3[vectnum * 6 - 6];
        mtriangles = new int[mvertices.Length];
        meshFilter = transform.GetOrAddComponent();
        meshrender = transform.GetOrAddComponent();
        mesh = meshFilter.mesh as Mesh;
        meshrender.material = new Material(Shader.Find("Unlit/Color"));
        meshrender.material.color = matcolor;
    }

    //  Mesh
    public void MeshBound(int xmin, int xmax, int ymin, int ymax, float maxheight)
    {
        //       \    
        botpoints[0] = toppoints[0] = Vector2.zero;
        botpoints[0].y = -maxheight;

        for (int i = 1; i < vectnum; i++)
        {
            if(i == vectnum - 2)
            {
                toppoints[i].x = toppoints[i - 1].x;
                toppoints[i].y = toppoints[0].y;
            }
            else if(i.isEven())
            {
                toppoints[i].x = toppoints[i - 1].x;
                toppoints[i].y = Random.Range(ymin, ymax);
            }
            else toppoints[i] = toppoints[i - 1] + Vector2.right * Random.Range(xmin, xmax);
            botpoints[i] = toppoints[i];
            botpoints[i].y = -maxheight;
        }

        //        
        for (int i = 0; i < roundpoints.Length; i++)
        {
            if (i < toppoints.Length) roundpoints[i] = toppoints[i];
            else if (i == roundpoints.Length - 1) roundpoints[i] = toppoints[0];
            else roundpoints[i] = botpoints[botpoints.Length * 2 - i - 1];
        }

        //  Mesh  
        for (int i = 0; i < vectnum; i++)
        {
            if (i * 6 > mvertices.Length - 6) break;
            mvertices[i * 6] = botpoints[i];
            mvertices[i * 6 + 1] = toppoints[i];
            mvertices[i * 6 + 2] = toppoints[i + 1];
            mvertices[i * 6 + 3] = botpoints[i];
            mvertices[i * 6 + 4] = toppoints[i + 1];
            mvertices[i * 6 + 5] = botpoints[i + 1];
        }

        //     
        //               
        for (int nIndex = 0; nIndex < mvertices.Length; nIndex++)
        {
            mtriangles[nIndex] = nIndex;
        }

        //  mesh
        mesh.Clear();
        mesh.vertices = mvertices;
        mesh.triangles = mtriangles;
        mesh.RecalculateBounds();
    }

    //    
    public void AddOutline(float linewide, Color linecolor, OutlingType ctype = OutlingType.up)
    {
        if(myline == null)
        {
            myline = gameObject.AddComponent();
            myline.material = new Material(Shader.Find("Particles/Alpha Blended"));
            myline.startWidth = myline.endWidth = linewide;
            myline.startColor = myline.endColor = linecolor;
            myline.useWorldSpace = false;
        }
        switch (ctype)
        {
            case OutlingType.up:
                myline.numPositions = toppoints.Length;
                for (int i = 0; i < myline.numPositions; i++)
                {
                    myline.SetPosition(i, toppoints[i]);
                }
                break;
            case OutlingType.down:
                myline.numPositions = botpoints.Length;
                for (int i = 0; i < myline.numPositions; i++)
                {
                    myline.SetPosition(i, botpoints[i]);
                }
                break;
            case OutlingType.all:
                myline.numPositions = roundpoints.Length;
                for (int i = 0; i < myline.numPositions; i++)
                {
                    myline.SetPosition(i, roundpoints[i]);
                }
                break;
        }
    }

    //     
    public void AddEdge2D()
    {
        EdgeCollider2D myedge = transform.GetOrAddComponent();
        myedge.points = roundpoints;
    }

    public Vector2[] WorldPoints(Vector2[] localpoints)
    {
        for(int i = 0; i < localpoints.Length; i++)
        {
            localpoints[i] += transform.position.IgnoreZAxis();
        }
        return localpoints;
    }
}
그 중에서 mesh 제작 부분은 구체적인 수요에 따라 사정을 참작하여 다시 쓸 수 있다. 내가 여기에서 실현한 것은 높고 낮은 기복이 있는 평평한 노면이다

좋은 웹페이지 즐겨찾기