본문 바로가기
Achaive

SPUM 최적화 처리 (드로우콜, 배칭)

by Client. DJ 2023. 5. 7.
반응형

최근 SPUM 에셋을 구매하여 사용 중인, 유저입니다. SPUM을 사용하다 보니 약간의 애로 사항이 생겼고, 관련되어서 해결법을 공유하고자 작성합니다. 주관적인 해결 방법일 수 있습니다.

기본적 제공되는 SPUM 캐릭터 프리팹을 사용하면, 캐릭터 프리팹 하나를 사용할 때마다. 대략 Batching 13~20 사이 정도가 발생합니다. 단순하게 10마리만 사용한다고 해도 대략 130 ~ 200에 육박하는 Batching 수치를 볼 수 있습니다.

원인

원인으로는 아래의 두 가지 내용이 있습니다.
1. 캐릭터에서 사용되는 리소스 이미지에 대한 아틀라스가 만들어지지 않은 상태의 단일 스프라이트 사용
2. 개별적으로 사용되는 메테리얼

아틀라스로 묶기

먼저 유니티에서도 아틀라스 사용을 권장하고 있습니다. 단순하게 이야기를 하자면 모든 리소스를 하나의 텍스쳐에 넣어 필요한 리소스들에 대해 좌표값만 수정하여 가져옵니다. 파일 로드를 할 때 비용이 크게 발생하는데 (연산), 이를 파일 로드 한 번으로 여러 개의 그림을 그릴 수 있도록 합니다.

 

1) 적당한 위치에서 아틀라스를 생성합니다.

아틀라스 생성

2) 해당 항목이 없다면 프로젝트의 패키지 매니저를 통해 스프라이트를 설치해주셔야합니다.

기본적으로 내장되어 있지 않은 경우가 있다.

3) 'SPUM'이라는 이름으로 생성했으며 아래와 같이 세팅했습니다.



4) Objects for Packing에 추가해야하는 항목은 총 3개입니다.
- Assets/Resources/SPUM/SPUM_Sprites
- Assets/SPUM/SPUM_Sprites
- Assets/SPUM/Res/Ect/Shadow

5) 세팅이 끝나면, 'Pack Preview'를 눌러줍니다.

아틀라스 생성 완료

6) 이렇게 되면, 하나의 파일을 통해 여러 개의 이미지를 사용하여 드로우콜을 줄일 수 있습니다.

메테리얼 통일 시키기

생성이된 SPUM 캐릭터들의 메테리얼이 통일되지 않았습니다. "SpriteDiffuse(SPUM 제공)"와 "Sprites/Default(유니티 빌트인)"를 섞어 사용 중입니다. 개별적인 메테리얼 사용은 랜더큐(Render Queue)에 따라 새로운 드로우콜을 발생 시킵니다.

이슈 내용을 확인해보면 제작자님이 조만간 업데이트해주실 것 같습니다. 이에 대해서 일단 저의 해결책은 기존 SPUM 에셋 플러그인은 건들지 않고, 스크립트 하나를 작성했습니다.

1) 에디터 스크립트 작성하기
SPUMEditor.cs

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

public class SPUMEditor : Editor
{
    [MenuItem("SPUM Editor/Resolution SPUM Prefab Material")]
    private static void ResolutionSPUMPrefabMaterial()
    {
        // Load Main Material
        Material spriteDiffuseMaterial = AssetDatabase.LoadAssetAtPath("Assets/SPUM/Res/Materials/SpriteDiffuse.mat", typeof(Material)) as Material;

        // Load SPUM Character Prefabs
        string folderPath = "Assets/Resources/SPUM/SPUM_Units/";
        string[] prefabGUIDs = AssetDatabase.FindAssets("t:Prefab", new[] { folderPath });
        for (int i = 0; i < prefabGUIDs.Length; i++)
        {
            string prefabGUID = prefabGUIDs[i];
            string prefabPath = AssetDatabase.GUIDToAssetPath(prefabGUID);
            var go = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);

            // Update SpriteRenderer Material
            SpriteRenderer[] spriteRenderers = go.GetComponentsInChildren<SpriteRenderer>();
            for (int j = 0; j < spriteRenderers.Length; j++)
            {
                SpriteRenderer spriteRenderer = spriteRenderers[j];
                spriteRenderer.material = spriteDiffuseMaterial;
            }
        }

        // Save
        AssetDatabase.SaveAssets();

        Debug.Log("Resolution SPUM Prefab Material!");
    }
}


2) 생성할 스크립트 위치

경로

위의 스크립트는 반드시 Editor 폴더 안에서 생성하시길 바랍니다. 유니티에서는 Editor 폴더 구분만으로도 실제 빌드에 포함되지 않도록 처리할 수 있습니다. (오직 에디터에서만 사용하는 기능을 위한 분류 처리)

3) 실행 방법

메뉴에서 실행할 수 있다.

위 기능을 사용하는 것만으로도, SPUM에서 사용 중인 "SpriteDiffuse" 메테리얼 하나로 통일할 수 있습니다.

결과

테스트 환경
- SPUM을 통해 랜덤 캐릭터 하나 생성
- 반복문을 통해 100마리 프리팹 로드
- 기본적인 배칭 카운트 12~13는 타일맵, 네비매시 사용을 위한 매시, 환경(라이트, 카메라 세팅) 등에서 발생하므로 계산에서 제외

1. SPUM으로 캐릭터 생성만 하고 바로 사용하는 경우 (Batching: 2000)

Batching: 2000

2. 아틀라스 생성 후 사용 (Batching: 600)

Batching: 600

3. 아틀라스 생성 및 메테리얼 통일 (Batching: 1)

Batching: 1

 

작업을 하다보면 특이점이 오게되는데, 나중이 될 최적화를 위한 작업입니다. 위 테스트 과정을 단순하게 이야기를 하자면, 2000번 그려야할 100마리의 캐릭터들을 단 한 번으로 그릴 수 있습니다. 이는 게임의 퍼포먼스와 직결되는 부분입니다.

최근 일주일 사이에 에셋을 구매하여 SPUM을 사용하게 되었는데, 모두가 양질의 개발을 했으면 하는 바람에 작성했습니다. 감사합니다.

참고

https://cafe.naver.com/soonsoondev/361
https://cafe.naver.com/soonsoondev/515

반응형

댓글