138 lines
4.2 KiB
C#
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");
|
|
}
|
|
}
|
|
} |