Unity Tips

Unity 2020.2버전 이상에서 빌드 할 때 Spine Mesh 최적화로 느려지는 문제

종잇장 2024. 3. 17. 15:42

개요

안녕하세요.

작업하는 프로젝트 빌드가 너무 오래 걸려 짬날 때마다 확인하다 Unity에서 Spine Runtime Package에서 원인을 찾아 포스팅으로 남겨봅니다.

  • Unity: 2022.1.15f1
  • Spine Package: spine-unity 4.0 2022-09-26 (Last updated: UTC - 2022 Sep 26)

 

 

발생 문제

빌드를 시작하면 `Begin` 이나 `BuildPreProcess` 단계에서 장시간 머물러있는 상황이었습니다.

 

Unloading 5 Unused Serialized files (Serialized files now loaded: 0)
Unloading 1364 unused Assets / (33.2 MB). Loaded Objects now: 5279.
Memory consumption went from 214.4 MB to 181.2 MB.
Total: 8.609800 ms (FindLiveObjects: 0.284900 ms CreateObjectMapping: 0.155200 ms MarkObjects: 5.443200 ms  DeleteObjects: 2.725600 ms)

위 상황이 계속되어 에디터 로그를 확인해 보니, 위 로그가 무수히 많이 나오고 오랜 시간 위와 같은 로그만 계속 올라오는 상황이 이어졌습니다.

(유니티 에디터 로그 파일 위치 https://docs.unity3d.com/Manual/LogFiles.html)

 

 

원인 파악

BuildPreProcess 단계에서 머물러있는 걸로 추측하여 스크립트에서 빌드 전에 실행하는 스크립트를 찾아보았습니다.

 

Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs

#if HAS_ON_POSTPROCESS_PREFAB
		internal static void PreprocessSpinePrefabMeshes () {
			BuildUtilities.IsInSkeletonAssetBuildPreProcessing = true;
			try {
				AssetDatabase.StartAssetEditing();
				prefabsToRestore.Clear();
				var prefabAssets = AssetDatabase.FindAssets("t:Prefab");
				foreach (var asset in prefabAssets) {
					string assetPath = AssetDatabase.GUIDToAssetPath(asset);
					GameObject prefabGameObject = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
					if (SpineEditorUtilities.CleanupSpinePrefabMesh(prefabGameObject)) {
#if HAS_SAVE_ASSET_IF_DIRTY
						AssetDatabase.SaveAssetIfDirty(prefabGameObject);
#endif
						prefabsToRestore.Add(assetPath);
					}
					EditorUtility.UnloadUnusedAssetsImmediate();
				}
				AssetDatabase.StopAssetEditing();
#if !HAS_SAVE_ASSET_IF_DIRTY
				if (prefabAssets.Length > 0)
					AssetDatabase.SaveAssets();
#endif
			} finally {
				BuildUtilities.IsInSkeletonAssetBuildPreProcessing = false;
			}
		}

Spine 에디터 코드 따라가 보면 위 코드가 나옵니다.

모든 Prefab을 로드해서 SpineEditorUtilities.CleanupSpinePrefabMesh 함수를 통해 일부 옵션들을 꺼주는 작업을 합니다.

 

위 코드에서 저희 프로젝트에 문제가 되었 부분은 모든 Prefab을 로드하는 부분이 문제였습니다.

규모가 큰 게임들을 작업하다 보면 Prefab이 Spine만 있는 게 아니고 모델링, UI, Effect.. 등등 다양한 곳에서 쓰고 있습니다.

Spine이 아닌 Prefab 까지 뒤지다 보니 너무 많이 느려지는 문제였습니다.

 

 

문제 해결

foreach (string asset in prefabAssets) {
	string assetPath = AssetDatabase.GUIDToAssetPath(asset);
	if (assetPath.StartsWith("Assets/Resources/Spine/") == false) continue;
	// ... //
}

Spine Prefab들이 있어야 하는 디렉토리 가 있어서, 경로 체크만 추가해 주었습니다.

덕분에 빌드시간이 반 이하로 줄었습니다.

만약에 따로 디렉토리 구분이 없다면 다른 방법을 고민해보셔야 합니다.

 

 

추가

https://github.com/EsotericSoftware/spine-runtimes/blob/4.1/CHANGELOG.md

Added Spine Preferences setting Prefabs - Optimize Preview Meshes. When enabled, Spine prefab preview meshes will be removed in a pre-build step to reduce build size. This increases build time as all prefabs in the project will be processed. Defaults to false to not slow down builds substantially every time.

위 문제는 4.1버전에서 옵션으로 제공하는 것으로 보입니다.

하지만, 옵션이 켜져있으면 이전의 문제가 그대로 발생할 것으로 보이니, 참고 바랍니다.