using System; using UnityEditor; using UnityEditor.Animations; using UnityEngine; namespace Colosseum.Editor { /// /// AnimatorController의 Skill 상태에 base clip을 일괄 할당하는 에디터 도구입니다. /// public static class BaseSkillClipAssigner { private const string SkillStateName = "Skill"; /// /// 선택한 애니메이션 클립을 모든 AnimatorController의 Skill 상태에 할당합니다. /// [MenuItem("Tools/Animation/Assign Base Skill Clip to All Controllers")] private static void AssignBaseClipToAllControllers() { AnimationClip selectedClip = Selection.activeObject as AnimationClip; if (selectedClip == null) { EditorUtility.DisplayDialog( "Base Skill Clip 할당", "Animations 폴더에서 할당할 AnimationClip을 선택한 후 다시 실행하세요.", "확인"); return; } string[] controllerGuids = AssetDatabase.FindAssets("t:AnimatorController", new[] { "Assets/_Game" }); int assignedCount = 0; for (int i = 0; i < controllerGuids.Length; i++) { string path = AssetDatabase.GUIDToAssetPath(controllerGuids[i]); AnimatorController ac = AssetDatabase.LoadAssetAtPath(path); if (ac == null) continue; if (TryAssignClipToState(ac, SkillStateName, selectedClip)) assignedCount++; } if (assignedCount > 0) { AssetDatabase.SaveAssets(); EditorUtility.DisplayDialog( "Base Skill Clip 할당 완료", $"{selectedClip.name}을(를) {assignedCount}개 컨트롤러의 Skill 상태에 할당했습니다.", "확인"); } else { EditorUtility.DisplayDialog( "Base Skill Clip 할당", "Skill 상태를 가진 컨트롤러를 찾지 못했습니다.", "확인"); } } /// /// AnimatorController의 지정한 상태에 클립을 할당합니다. /// private static bool TryAssignClipToState(AnimatorController ac, string stateName, AnimationClip clip) { for (int i = 0; i < ac.layers.Length; i++) { if (TryAssignClipInStateMachine(ac.layers[i].stateMachine, stateName, clip)) { EditorUtility.SetDirty(ac); return true; } } return false; } /// /// StateMachine을 재귀적으로 탐색하여 지정한 이름의 상태에 클립을 할당합니다. /// private static bool TryAssignClipInStateMachine(AnimatorStateMachine sm, string stateName, AnimationClip clip) { for (int i = 0; i < sm.states.Length; i++) { if (sm.states[i].state.name == stateName) { sm.states[i].state.motion = clip; return true; } } for (int i = 0; i < sm.stateMachines.Length; i++) { if (TryAssignClipInStateMachine(sm.stateMachines[i].stateMachine, stateName, clip)) return true; } return false; } } }