using UnityEngine; using UnityEditor; using KindRetargeting; [CustomEditor(typeof(FullBodyInverseKinematics))] public class FullBodyInverseKinematicsEditor : BaseRetargetingEditor { // Foldout 상태를 저장할 변수들 private bool showBasicSettings = true; private bool showLimbSettings = false; private bool[] showLimbs = new bool[4]; // 0: leftArm, 1: rightArm, 2: leftLeg, 3: rightLeg // SerializedProperty 변수들 private SerializedProperty animatorProp; private SerializedProperty iterationsProp; private SerializedProperty deltaThresholdProp; private SerializedProperty[] limbProps; private readonly string[] limbNames = { "Left Arm", "Right Arm", "Left Leg", "Right Leg" }; private readonly string[] limbPropNames = { "leftArm", "rightArm", "leftLeg", "rightLeg" }; protected override void OnEnable() { base.OnEnable(); // SerializedProperty 초기화 animatorProp = serializedObject.FindProperty("animator"); iterationsProp = serializedObject.FindProperty("iterations"); deltaThresholdProp = serializedObject.FindProperty("deltaThreshold"); // Limb Properties 초기화 limbProps = new SerializedProperty[4]; for (int i = 0; i < 4; i++) { limbProps[i] = serializedObject.FindProperty(limbPropNames[i]); } } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.Space(5); // 기본 설정 섹션 showBasicSettings = EditorGUILayout.Foldout(showBasicSettings, "IK 기본 설정", true); if (showBasicSettings) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(iterationsProp); EditorGUILayout.PropertyField(deltaThresholdProp); EditorGUI.indentLevel--; } EditorGUILayout.Space(5); // Limb Settings 섹션 showLimbSettings = EditorGUILayout.Foldout(showLimbSettings, "Limb Settings", true); if (showLimbSettings) { EditorGUI.indentLevel++; // 각 Limb에 대한 Foldout for (int i = 0; i < 4; i++) { EditorGUILayout.BeginVertical(GUI.skin.box); showLimbs[i] = EditorGUILayout.Foldout(showLimbs[i], limbNames[i], true); if (showLimbs[i]) { DrawLimbIK(limbProps[i]); } EditorGUILayout.EndVertical(); } EditorGUI.indentLevel--; } serializedObject.ApplyModifiedProperties(); } private void DrawLimbIK(SerializedProperty limbProp) { EditorGUI.indentLevel++; // Enable IK 토글 추가 SerializedProperty enableIKProp = limbProp.FindPropertyRelative("enableIK"); EditorGUILayout.PropertyField(enableIKProp, new GUIContent("Enable IK")); EditorGUILayout.Space(2); // IK가 활성화된 경우에만 나머지 설정들을 표시 if (enableIKProp.boolValue) { // End Target 설정 SerializedProperty endTargetProp = limbProp.FindPropertyRelative("endTarget"); EditorGUILayout.PropertyField(endTargetProp.FindPropertyRelative("target"), new GUIContent("End Target")); EditorGUILayout.Slider(endTargetProp.FindPropertyRelative("weight"), 0f, 1f, new GUIContent("End Weight")); EditorGUILayout.Space(2); // Middle Target 설정 SerializedProperty middleTargetProp = limbProp.FindPropertyRelative("middleTarget"); EditorGUILayout.PropertyField(middleTargetProp.FindPropertyRelative("target"), new GUIContent("Middle Target")); EditorGUILayout.Slider(middleTargetProp.FindPropertyRelative("weight"), 0f, 1f, new GUIContent("Middle Weight")); // 발목 타겟 설정 EditorGUILayout.Space(2); SerializedProperty ankleTargetProp = limbProp.FindPropertyRelative("ankleTarget"); EditorGUILayout.PropertyField(ankleTargetProp.FindPropertyRelative("target"), new GUIContent("Ankle Target")); EditorGUILayout.Slider(ankleTargetProp.FindPropertyRelative("weight"), 0f, 1f, new GUIContent("Ankle Weight")); } EditorGUI.indentLevel--; } }