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;
}
}
}