애니메이션 추가

This commit is contained in:
2026-09-01 20:19:59 +09:00
parent 01c852fef9
commit 7ec587353a
1542 changed files with 585048 additions and 21 deletions

View File

@@ -0,0 +1,82 @@
using UnityEditor;
using UnityEditor.Animations;
using UnityEditor.SceneManagement;
using UnityEngine;
/// <summary>
/// 애니메이션 배선을 씬에 넣고, 상태 이름이 맞춰진 빈 Animator Controller 를 만들어 준다.
///
/// 컨트롤러를 손으로 만들면 상태 이름을 CharacterMotionDirector 의 필드와 일일이
/// 맞춰야 하는데, 오타 하나면 조용히 아무 일도 안 일어난다. 그 자리를 없앤다.
/// </summary>
public static class CharacterMotionSetupMenu
{
const string ObjectName = "CharacterMotion";
const string ControllerPath = "Assets/99_Settings/CharacterMotion.controller";
[MenuItem("Tools/Desktop Overlay/10. Add Character Motion To Scene")]
public static void AddMotionDirector()
{
var existing = Object.FindFirstObjectByType<CharacterMotionDirector>();
if (existing != null)
{
Selection.activeGameObject = existing.gameObject;
EditorGUIUtility.PingObject(existing.gameObject);
Debug.Log($"[CharacterMotionSetupMenu] 이미 있습니다: {existing.gameObject.name}");
return;
}
var go = new GameObject(ObjectName);
Undo.RegisterCreatedObjectUndo(go, "Add Character Motion");
go.AddComponent<CharacterMotionDirector>();
Selection.activeGameObject = go;
EditorSceneManager.MarkSceneDirty(go.scene);
Debug.Log(
"[CharacterMotionSetupMenu] CharacterMotion 을 추가했습니다. 씬을 저장(Ctrl+S)하세요.\n" +
"Motion Controller 가 비어 있으면 지금처럼 ProceduralIdle 로 동작합니다.\n" +
"메뉴 11 로 빈 컨트롤러를 만들고 클립을 채워 넣으세요.");
}
[MenuItem("Tools/Desktop Overlay/11. Create Motion Controller")]
public static void CreateController()
{
if (AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(ControllerPath) != null)
{
Debug.LogWarning($"[CharacterMotionSetupMenu] 이미 있습니다: {ControllerPath}\n" +
"덮어쓰지 않습니다. 지우고 다시 실행하세요.");
Selection.activeObject = AssetDatabase.LoadAssetAtPath<Object>(ControllerPath);
return;
}
var controller = AnimatorController.CreateAnimatorControllerAtPath(ControllerPath);
var layer = controller.layers[0];
var machine = layer.stateMachine;
// CharacterMotionDirector 의 기본 이름과 같아야 한다.
var idle = machine.AddState("Idle");
machine.AddState("Fall");
machine.AddState("Walk");
machine.AddState("Jump");
machine.AddState("Sit");
machine.AddState("LieDown");
// 전환은 코드에서 CrossFade 로 직접 하므로 트랜지션을 만들지 않는다.
// 상태만 있으면 된다.
machine.defaultState = idle;
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Selection.activeObject = controller;
EditorGUIUtility.PingObject(controller);
Debug.Log(
$"[CharacterMotionSetupMenu] 컨트롤러를 만들었습니다: {ControllerPath}\n" +
"각 상태(Idle / Fall / Walk / Jump / Sit / LieDown)에 Humanoid 클립을 넣으세요.\n" +
"당장 없는 것은 비워둬도 됩니다 — 그 몸짓은 건너뛰고 이전 자세를 유지합니다.\n" +
"FBX 는 임포트 설정에서 Rig > Animation Type = Humanoid 여야 리타게팅됩니다.\n" +
"다 채운 뒤 CharacterMotionDirector 의 Motion Controller 에 연결하세요.");
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2ffe87e09d3787a44ac9f6cb3c4cb4cf

View File

@@ -12,7 +12,7 @@ public static class ChatSetupMenu
{
const string ObjectName = "ChatSystem";
[MenuItem("Tools/Desktop Overlay/6. Add Chat Window To Scene")]
[MenuItem("Tools/Desktop Overlay/8. Add Chat Window To Scene")]
public static void AddChatSystem()
{
var existing = Object.FindFirstObjectByType<ChatController>();
@@ -44,7 +44,7 @@ public static void AddChatSystem()
$"(파일로 직접 넣으려면 {ChatConfig.ConfigPath}, 또는 환경 변수 ANTHROPIC_API_KEY)");
}
[MenuItem("Tools/Desktop Overlay/7. Open Chat Config Folder")]
[MenuItem("Tools/Desktop Overlay/9. Open Chat Config Folder")]
public static void OpenConfigFolder()
{
string dir = ChatConfig.ConfigDirectory;