본문 바로가기
개발/Unity

유니티 - CombineInstance로 메시 합치기 (Combine Meshes with CombineInstance)

by 피로물든딸기 2022. 11. 7.
반응형

Unity 전체 링크

 

참고 

- 드로우 콜 횟수 최적화하기 (Optimizing Draw Calls, Batches)

 

Quad 5개가 그림과 같이 배치되어 있다.

5개 오브젝트의 mesh를 하나로 합쳐보자.


Mesh 정보를 불러올 오브젝트들을 public으로 선언한다.

    public GameObject[] go;

 

오브젝트에서 MeshFilter의 정보를 얻은 다음, mesh를 CombineInstance에 넣어주고, 좌표도 전환한다.

meshFilters의 transform(=GameObject의 transform)의 로컬 좌표를 월드 좌표로 전환해서 넣어준다.

    MeshFilter[] meshFilters = new MeshFilter[go.Length];
    CombineInstance[] combine = new CombineInstance[meshFilters.Length];

    for(int i = 0; i < meshFilters.Length; i++)
    {
        meshFilters[i] = go[i].GetComponent<MeshFilter>();
        combine[i].mesh = meshFilters[i].mesh;
        combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
    }

 

참고로Combine의 transform은 Matrix4x4 타입이다.

 

이제 현재의 오브젝트의 mesh에 위에서 모은 mesh를 CombineMeshes로 합친다.

그리고 콜라이더도 추가해두자.

    Mesh mesh = this.transform.GetComponent<MeshFilter>().mesh;

    mesh.Clear();
    mesh.CombineMeshes(combine);

    this.gameObject.AddComponent<MeshCollider>();

 

마지막으로 만든 mesh를 저장하자.

#if UNITY_EDITOR
using UnityEditor;
#endif

#if UNITY_EDITOR
        { // Mesh 저장
            string path = "Assets/MyMesh.asset";
            AssetDatabase.CreateAsset(transform.GetComponent<MeshFilter>().mesh, AssetDatabase.GenerateUniqueAssetPath(path));
            AssetDatabase.SaveAssets();
        }
#endif

 

빈 오브젝트에 CombineMesh.cs, Mesh Filter, Mesh Renderer, Default-Material을 추가하자.

그리고 쿼드 5개를 할당한다.

 

게임을 실행하면 빈 오브젝트에 합쳐진 쿼드들이 생긴다.

메시가 하나로 합쳐진 것을 알 수 있다.

 

참고로 메시가 합쳐졌지만 메시를 새로 그리는 것은 아니다.

Mesh 정보를 바탕으로 삼각분할하지 않고 아래와 같이 그냥 통째로 붙어있다.

Wireframe이나 콜라이더를 보면 그림과 메시를 한 덩어리로 관리할 뿐 새로 그리지는 않는다.

 

전체 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class CombineMesh : MonoBehaviour
{
    public GameObject[] go;

    void Start()
    {
        MeshFilter[] meshFilters = new MeshFilter[go.Length];
        CombineInstance[] combine = new CombineInstance[meshFilters.Length];

        for(int i = 0; i < meshFilters.Length; i++)
        {
            meshFilters[i] = go[i].GetComponent<MeshFilter>();
            combine[i].mesh = meshFilters[i].mesh;
            combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
        }

        Mesh mesh = this.transform.GetComponent<MeshFilter>().mesh;

        mesh.Clear();
        mesh.CombineMeshes(combine);

        this.gameObject.AddComponent<MeshCollider>();

#if UNITY_EDITOR
        { // Mesh 저장
            string path = "Assets/MyMesh.asset";
            AssetDatabase.CreateAsset(transform.GetComponent<MeshFilter>().mesh, AssetDatabase.GenerateUniqueAssetPath(path));
            AssetDatabase.SaveAssets();
        }
#endif
    }

}

 

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

CombineMeshs.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

반응형

댓글