개요

안녕하세요.
작업하는 프로젝트 빌드가 너무 오래 걸려 짬날 때마다 확인하다 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 단계에서 머물러있는 걸로 추측하여 스크립트에서 빌드 전에 실행하는 스크립트를 찾아보았습니다.
- 2018.2버전 이전: IPreprocessBuild.OnPreprocessBuild
- 2018.2버전 이후: IPreprocessBuildWithReport.OnPreprocessBuild
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버전에서 옵션으로 제공하는 것으로 보입니다.
하지만, 옵션이 켜져있으면 이전의 문제가 그대로 발생할 것으로 보이니, 참고 바랍니다.
'Unity Tips' 카테고리의 다른 글
C# Dictionary를 foreach로 탐색할 때 Values 프로퍼티를 사용하세요 (3) | 2024.10.27 |
---|---|
UniTask 사용 후기 (0) | 2024.08.04 |
NSprites - Unity ECS용 Sprite Renderer, Sprite Animation 프레임워크 (1) | 2023.11.19 |
Unity Entities - Job에서 EntityManager, EntityCommandBuffer 사용 방법 (0) | 2023.07.04 |
Unity Entities - System에서 Collections(NativeArray, NativeList ...) Dispose함수를 Job 이후에 실행하는 방법 (0) | 2023.07.04 |