카테고리 없음

코드로 Mesh 만들기

zelkova 2021. 4. 1. 14:45

<목차로 돌아가기>

 

참조 : catlikecoding.com/unity/tutorials/procedural-grid/

단순히 삼각형 두개를 이어서 네모 만들어봄.
using System.Collections;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class GridTest : MonoBehaviour
{
    public int xSize, ySize;
    private Vector3[] vertices;
        private void Awake() {
        StartCoroutine(Generated());
    }

    private Mesh mesh;

    IEnumerator Generated() {

        //메쉬 만들고
        GetComponent<MeshFilter>().mesh = mesh = new Mesh();
        GetComponent<MeshRenderer>().material = new Material(Shader.Find("Universal Render Pipeline/Lit"));
        mesh.name = "Procedural Grid";
        
        // Gizmo로 점찍기
        vertices = new Vector3[(xSize + 1) * (ySize + 1)];
        for(int i=0, y=0; y <= ySize; y++) {
            for(int x =0; x<=xSize; x++, i++) {
                vertices[i] = new Vector3(x, y);
                yield return new WaitForSeconds(0.1f);
            }
        }
        //mesh에 점출력
        mesh.vertices = vertices;

        int[] triangles = new int[6];
        triangles[0] = 0;
        triangles[1] = xSize + 1;
        triangles[2] = 1;
        triangles[3] = 1;
        triangles[4] = xSize + 1;
        triangles[5] = xSize + 2;
        mesh.triangles = triangles;

        yield return null;
    }

    private void OnDrawGizmos() {
        if (vertices == null) {
            return;
        }
        
        Gizmos.color = Color.black;
        for(int i=0; i < vertices.Length; i++) {
            Gizmos.DrawSphere(vertices[i], 0.1f);
        }
    }
}

 

triangles 같은 값을 공유하므로 아래와 같이 바꾸기 가능

        triangles[0] = 0;
        triangles[2] = triangles[3] = 1;
        triangles[1] = triangles[4] = xSize + 1;
        triangles[5] = xSize + 2;

 

이걸 단일 반복문으로 바꾸면 

        for(int ti =0, vi = 0, x = 0; x < xSize; x++, ti += 6, vi++) {
            triangles[ti] = vi;
            triangles[ti + 3] = triangles[ti + 2] = vi + 1;
            triangles[ti + 4] = triangles[ti + 1] = vi + xSize + 1;
            triangles[ti + 5] = vi + xSize + 2;
            yield return null;
        }

 

한줄이 아니라 모든 줄을 채우도록 바꾸면

using System.Collections;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class GridTest : MonoBehaviour
{
    public int xSize, ySize;
    private Vector3[] vertices;
        private void Awake() {
        StartCoroutine(Generated());
    }

    private Mesh mesh;

    IEnumerator Generated() {

        //메쉬 만들고
        GetComponent<MeshFilter>().mesh = mesh = new Mesh();
        GetComponent<MeshRenderer>().material = new Material(Shader.Find("Universal Render Pipeline/Lit"));
        mesh.name = "Procedural Grid";
        
        // Gizmo로 점찍기
        vertices = new Vector3[(xSize + 1) * (ySize + 1)];
        for(int i=0, y=0; y <= ySize; y++) {
            for(int x =0; x<=xSize; x++, i++) {
                vertices[i] = new Vector3(x, y);
            }
        }
        //mesh에 점출력
        mesh.vertices = vertices;

        //int[] triangles = new int[6];
        //triangles[0] = 0;
        //triangles[2] = triangles[3] = 1;
        //triangles[1] = triangles[4] = xSize + 1;
        //triangles[5] = xSize + 2;
        //mesh.triangles = triangles;

        int[] triangles = new int[xSize * ySize * 6];
        for (int ti = 0, vi = 0, y = 0; y < ySize; y++, vi++) {
            for (int x = 0; x < xSize; x++, ti += 6, vi++) {
                triangles[ti] = vi;
                triangles[ti + 3] = triangles[ti + 2] = vi + 1;
                triangles[ti + 4] = triangles[ti + 1] = vi + xSize + 1;
                triangles[ti + 5] = vi + xSize + 2;
                yield return null;
            }
        }

        mesh.triangles = triangles;

    }

    private void OnDrawGizmos() {
        if (vertices == null) {
            return;
        }
        
        Gizmos.color = Color.black;
        for(int i=0; i < vertices.Length; i++) {
            Gizmos.DrawSphere(vertices[i], 0.1f);
        }
    }
}

 

 

현재는 빛을 받지 않아서 어둡게 나오는데.. nomal값을 자동으로 계산하게 하면 노말값에 따른 빛의 계산이 이뤄지는 것을 확인.

mesh.RecalculateNormals();

 

UV계산하여 텍스쳐 나타내기

 

using System.Collections;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class GridTest : MonoBehaviour
{
    public int xSize, ySize;
    private Vector3[] vertices;
        private void Awake() {
        StartCoroutine(Generated());
    }

    private Mesh mesh;

    IEnumerator Generated() {

        //메쉬 만들고
        GetComponent<MeshFilter>().mesh = mesh = new Mesh();
        mesh.name = "Procedural Grid";
        
        // Gizmo로 점찍기
        vertices = new Vector3[(xSize + 1) * (ySize + 1)];
        Vector2[] uv = new Vector2[vertices.Length];
        for (int i=0, y=0; y <= ySize; y++) {
            for(int x =0; x<=xSize; x++, i++) {
                vertices[i] = new Vector3(x, y);
                uv[i] = new Vector2(x / xSize, y / ySize);
            }
        }
        

        int[] triangles = new int[xSize * ySize * 6];
        
        for (int ti = 0, vi = 0, y = 0; y < ySize; y++, vi++) {
            for (int x = 0; x < xSize; x++, ti += 6, vi++) {
                triangles[ti] = vi;
                triangles[ti + 3] = triangles[ti + 2] = vi + 1;
                triangles[ti + 4] = triangles[ti + 1] = vi + xSize + 1;
                triangles[ti + 5] = vi + xSize + 2;
                yield return null;
            }
        }
        
        mesh.vertices = vertices; //점 계산
        mesh.uv = uv; // UV 출력
        mesh.triangles = triangles; // 삼각형 계산
        mesh.RecalculateNormals(); //노말 계산
    }

    private void OnDrawGizmos() {
        if (vertices == null) {
            return;
        }
        
        Gizmos.color = Color.black;
        for(int i=0; i < vertices.Length; i++) {
            Gizmos.DrawSphere(vertices[i], 0.1f);
        }
    }
}

 

 

 

 

UV가 똑바로 출력안되면 아래와 같이 (float)으로 형변환하면 해결됨.

 

        // Gizmo로 점찍기
        vertices = new Vector3[(xSize + 1) * (ySize + 1)];
        Vector2[] uv = new Vector2[vertices.Length];
        for (int i=0, y=0; y <= ySize; y++) {
            for(int x =0; x<=xSize; x++, i++) {
                vertices[i] = new Vector3(x, y);
                uv[i] = new Vector2((float)x / xSize, (float)y / ySize);
            }
        }
        

 

반응형