본문 바로가기
유니티/절차적 생성

[유니티] 절차적 지형 생성 3 - Texture

by 개발자 박근영 2021. 11. 15.

목표

이전 포스팅에서 생성한 지형에 텍스처를 적용한다.


지형 텍스처는 6면체에서 위, 아래, 옆면 이렇게 총 3가지로 구성된다. 적용될 머티리얼은 다음 사진과 같다.

그리고 이 머티리얼을 단순히 메쉬에 적용하면 될 것 같지만 아니다. 앞서 최적화를 위해 메쉬를 하나로 합쳐놓았기 때문에 각기 다른 머티리얼을 사용하려면 메쉬를 머티리얼에 맞춰 분리해야하며, 분리된 메쉬를 다시 하나의 메쉬로 통합하는 작업이 필요하다.

단일 메쉬 단일 머티리얼 복합 메쉬 복합 머티리얼 단일 메쉬 복합 머티리얼

소스 코드

public void Combine(MeshFilter[] meshFilters, MeshRenderer[] meshRenderers)
{
    //지형 메쉬에서 머티리얼 종류를 가져옴
    List<Material> materials = new List<Material>();
    for (int i = 0; i < meshRenderers.Length; i++)
    {
        if (!materials.Contains(meshRenderers[i].sharedMaterial))
        {
            //종류가 다른 머티리얼만 리스트에 추가
            materials.Add(meshRenderers[i].sharedMaterial);
        }
    }
    
    List<Mesh> meshes = new List<Mesh>(); //머티리얼 종류에 맞춰 분리된 메쉬가 담길 변수
    for (int i = 0; i < materials.Count; i++)
    {
        List<CombineInstance> combine = new List<CombineInstance>();
        for (int j = 0; j < meshFilters.Length; j++)
        {
            //현재 머티리얼에 해당하는 메쉬만 가져온 뒤 CombineInstance에 저장
            if (materials[i] == meshRenderers[j].sharedMaterial)
            {
                CombineInstance ci = new CombineInstance();
        
                ci.mesh = meshFilters[j].sharedMesh;
                ci.transform = meshFilters[j].transform.localToWorldMatrix;
                ci.subMeshIndex = 0;
                combine.Add(ci);
                meshFilters[j].gameObject.SetActive(false);
            }
        }
        //CombineInstance에 저장된 메쉬들을 하나로 통합
        Mesh mesh = new Mesh();
        mesh.CombineMeshes(combine.ToArray(), true);
        meshes.Add(mesh); //통합한 메쉬를 위에 선언한 리스트에 저장
        //위, 아래, 옆면 총 3가지의 통합된 메쉬가 저장됨
   }
        
    List<CombineInstance> combineFinal = new List<CombineInstance>();
    for (int i = 0; i < meshes.Count; i++) //위, 아래, 옆면 총 3회 반복
    {
        CombineInstance ci = new CombineInstance();
        ci.mesh = meshes[i];
        ci.transform = Matrix4x4.identity;
        ci.subMeshIndex = 0;
        combineFinal.Add(ci);
    }
        
    meshFilter.mesh.CombineMeshes(combineFinal.ToArray(), false);
    meshRenderer.materials = materials.ToArray();
    meshCollider.sharedMesh = meshFilter.sharedMesh;
    gameObject.SetActive(true);
}

최종 결과


참고한 사이트

https://www.youtube.com/watch?v=6APzUgckV7U

 

댓글