Streamingle_URP/Assets/Scripts/Editor/HumanPoseClipApplier.cs

138 lines
4.2 KiB
C#

using UnityEngine;
using UnityEditor;
using System.IO;
using UniHumanoid;
using UniGLTF;
[System.Serializable]
public class HumanPoseData
{
public Vector3 bodyPosition;
public Quaternion bodyRotation;
public float[] muscles;
}
public class HumanPoseClipApplier : EditorWindow
{
private Animator targetAnimator;
private HumanPoseClip poseClip;
private string jsonPath;
private bool useJsonFile = false;
[MenuItem("Tools/Animation/Apply Human Pose Clip")]
public static void ShowWindow()
{
GetWindow<HumanPoseClipApplier>("Human Pose Clip Applier");
}
private void OnGUI()
{
GUILayout.Label("Apply Human Pose Clip to Animator", EditorStyles.boldLabel);
EditorGUILayout.Space();
targetAnimator = (Animator)EditorGUILayout.ObjectField("Target Animator", targetAnimator, typeof(Animator), true);
EditorGUILayout.Space();
useJsonFile = EditorGUILayout.Toggle("Use JSON File", useJsonFile);
if (useJsonFile)
{
EditorGUILayout.BeginHorizontal();
jsonPath = EditorGUILayout.TextField("JSON File Path", jsonPath);
if (GUILayout.Button("Browse", GUILayout.Width(60)))
{
string path = EditorUtility.OpenFilePanel("Select JSON File", "", "json");
if (!string.IsNullOrEmpty(path))
{
jsonPath = path;
}
}
EditorGUILayout.EndHorizontal();
}
else
{
poseClip = (HumanPoseClip)EditorGUILayout.ObjectField("Pose Clip", poseClip, typeof(HumanPoseClip), false);
}
EditorGUILayout.Space();
bool canApply = targetAnimator != null &&
((useJsonFile && !string.IsNullOrEmpty(jsonPath)) || (!useJsonFile && poseClip != null));
GUI.enabled = canApply;
if (GUILayout.Button("Apply Pose Clip"))
{
ApplyPoseClip();
}
GUI.enabled = true;
}
private void ApplyPoseClip()
{
if (targetAnimator == null)
{
EditorUtility.DisplayDialog("Error", "Please select an Animator!", "OK");
return;
}
HumanPose pose;
if (useJsonFile)
{
if (string.IsNullOrEmpty(jsonPath) || !File.Exists(jsonPath))
{
EditorUtility.DisplayDialog("Error", "Please select a valid JSON file!", "OK");
return;
}
// JSON 파일에서 데이터 로드
string jsonContent = File.ReadAllText(jsonPath);
HumanPoseData poseData = JsonUtility.FromJson<HumanPoseData>(jsonContent);
// HumanPose로 변환
pose = new HumanPose
{
bodyPosition = poseData.bodyPosition,
bodyRotation = poseData.bodyRotation,
muscles = poseData.muscles
};
}
else if (poseClip != null)
{
pose = poseClip.GetPose();
}
else
{
EditorUtility.DisplayDialog("Error", "Please select a Pose Clip!", "OK");
return;
}
var animator = targetAnimator;
var avatar = animator.avatar;
if (avatar == null || !avatar.isHuman)
{
EditorUtility.DisplayDialog("Error", "Selected Animator must have a Humanoid Avatar!", "OK");
return;
}
try
{
// HumanPoseHandler를 사용하여 포즈 데이터 적용
var handler = new HumanPoseHandler(avatar, animator.transform);
// 포즈 적용
handler.SetHumanPose(ref pose);
// 변경사항 저장
EditorUtility.SetDirty(animator);
Debug.Log("Pose clip has been applied to the Animator");
EditorUtility.DisplayDialog("Success", "Pose clip has been applied to the Animator", "OK");
}
catch (System.Exception e)
{
Debug.LogError($"Error applying pose clip: {e.Message}");
EditorUtility.DisplayDialog("Error", $"Failed to apply pose clip: {e.Message}", "OK");
}
}
}