참고
- 드로우 콜 횟수 최적화하기 (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에서 확인 가능하다.
Unity Plus:
Unity Pro:
Unity 프리미엄 학습:
댓글