본문 바로가기
개발/Unity

유니티 - 절차적 메시로 정다각형, 원 만들기 (Make Regular Polygon, Circle with Procedural Mesh)

by 피로물든딸기 2022. 10. 31.
반응형

Unity 전체 링크

 

절차적 메시로 삼각형을 만들고 size와 offset을 변경하였으므로, 이 내용을 수정하여 정다각형과 원을 만들어보자.

polygon 변수를 public으로 수정하고 OnValidate도 3이상일 때 Mesh를 그리도록 수정한다.

    public int polygon = 3;

    void OnValidate()
    {
        if (mesh == null) return;

        if (size > 0 || offset.magnitude > 0 || polygon >= 3)
        {
            setMeshData(size, polygon);
            createProceduralMesh();
        }
    }

 

정 N각형중심 좌표 1개N개의 좌표로 이루어져 있다.

따라서 vertices에 좌표는 아래처럼 변경된다.

가운데 점 (0, 0, 0)을 기준으로 좌표를 원형으로 배치하였다.

    vertices = new Vector3[polygon + 1];
       
    vertices[0] = new Vector3(0, 0, 0) + offset;
    for (int i = 1; i <= polygon; i++)
    {
        float angle = -i * (Mathf.PI * 2.0f) / polygon;

        vertices[i]
            = (new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * size) + offset;
    }

 

정 N각형의 삼각형은 중점 좌표를 공유하고 있으므로 아래와 같이 triangles에 담는다.

마지막 좌표는 따로 예외 처리 한다. (각 정점을 서로 공유하도록 하였다.)

    triangles = new int[3 * polygon];
    for (int i = 0; i < polygon - 1; i++)
    {
        triangles[i * 3] = 0;
        triangles[i * 3 + 1] = i + 1;
        triangles[i * 3 + 2] = i + 2;
    }

    triangles[3 * polygon - 3] = 0;
    triangles[3 * polygon - 2] = polygon;
    triangles[3 * polygon - 1] = 1;

 

이제 게임을 실행해서 polygon을 변경하면 정 N각형을 만들 수 있다.

 

polygon을 계속 늘리면 늘릴수록 실제 원에 가깝지만, 메시가 많아지므로 과부하가 생길 수 있다.

참고로 유니티에서 제공하는 실린더(Cylinder)의 메시를 보면 원이 아니라 정 20각형이다.

 

전체 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class ProceduralRegular : MonoBehaviour
{
    public int polygon = 3;
    public float size = 1.0f;
    public Vector3 offset = new Vector3(0, 0, 0);

    Mesh mesh;
    Vector3[] vertices;
    int[] triangles;

    void OnValidate()
    {
        if (mesh == null) return;

        if (size > 0 || offset.magnitude > 0 || polygon >= 3)
        {
            setMeshData(size, polygon);
            createProceduralMesh();
        }
    }

    void Start()
    {
        mesh = GetComponent<MeshFilter>().mesh;

        setMeshData(size, polygon);
        createProceduralMesh();
    }

    void setMeshData(float size, int polygon)
    {
        vertices = new Vector3[polygon + 1];
       
        vertices[0] = new Vector3(0, 0, 0) + offset;
        for (int i = 1; i <= polygon; i++)
        {
            float angle = -i * (Mathf.PI * 2.0f) / polygon;

            vertices[i]
                = (new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * size) + offset;
        }

        triangles = new int[3 * polygon];
        for (int i = 0; i < polygon - 1; i++)
        {
            triangles[i * 3] = 0;
            triangles[i * 3 + 1] = i + 1;
            triangles[i * 3 + 2] = i + 2;
        }

        triangles[3 * polygon - 3] = 0;
        triangles[3 * polygon - 2] = polygon;
        triangles[3 * polygon - 1] = 1;
    }

    void createProceduralMesh()
    {
        mesh.Clear();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();

        Destroy(this.GetComponent<MeshCollider>());
        this.gameObject.AddComponent<MeshCollider>();
    }
}

 

위의 실행결과는 아래의 unitypackage에서 확인 가능하다.

ProceduralRegularPolygon.unitypackage
0.00MB

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글