Streamingle_URP/Assets/Scripts/KindRetargeting/Editor/FingerShapedControllerEditor.cs

260 lines
8.7 KiB
C#

using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(FingerShapedController))]
public class FingerShapedControllerEditor : Editor
{
private bool showLeftHand = true;
private bool showRightHand = true;
private const float SLIDER_HEIGHT = 100f;
private const float SLIDER_WIDTH = 25f;
private const float SPACING = 5f;
public override void OnInspectorGUI()
{
FingerShapedController controller = (FingerShapedController)target;
// 활성화/비활성화 토글
EditorGUI.BeginChangeCheck();
bool isEnabled = EditorGUILayout.Toggle("손가락 제어 활성화", controller.enabled);
if (EditorGUI.EndChangeCheck())
{
controller.enabled = isEnabled;
EditorUtility.SetDirty(controller);
}
if (!controller.enabled) return;
serializedObject.Update();
// 왼손/오른손 컨트롤
DrawHandControls("왼손", "left", ref showLeftHand);
EditorGUILayout.Space(SPACING);
DrawHandControls("오른손", "right", ref showRightHand);
EditorGUILayout.Space(SPACING);
// 프리셋 버튼들
DrawPresetButtons(controller);
serializedObject.ApplyModifiedProperties();
}
private void DrawHandControls(string label, string prefix, ref bool foldout)
{
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
// 헤더 줄
EditorGUILayout.BeginHorizontal();
// 폴드아웃과 활성화 토글을 나란히 배치
EditorGUILayout.BeginHorizontal(GUILayout.Width(200));
foldout = EditorGUILayout.Foldout(foldout, label, true);
SerializedProperty handEnabledProp = serializedObject.FindProperty($"{prefix}HandEnabled");
bool handEnabled = EditorGUILayout.Toggle("제어 활성화", handEnabledProp.boolValue);
if (handEnabled != handEnabledProp.boolValue)
{
handEnabledProp.boolValue = handEnabled;
if (handEnabled && !((FingerShapedController)target).enabled)
{
((FingerShapedController)target).enabled = true;
}
}
EditorGUILayout.EndHorizontal();
// 초기화 버튼
if (GUILayout.Button("초기화", GUILayout.Width(60)))
{
ResetHandValues(prefix);
}
EditorGUILayout.EndHorizontal();
// 해당 손이 활성화된 경우에만 컨트롤 표시
if (foldout && handEnabledProp.boolValue)
{
EditorGUILayout.Space(SPACING);
DrawFingerSliders(prefix);
EditorGUILayout.Space(SPACING);
DrawSpreadSlider(prefix);
}
EditorGUILayout.EndVertical();
}
private void DrawFingerSliders(string prefix)
{
string[] fingerNames = { "Thumb", "Index", "Middle", "Ring", "Pinky" };
float totalWidth = (SLIDER_WIDTH + SPACING) * fingerNames.Length;
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.BeginHorizontal(GUILayout.Width(totalWidth));
for (int i = 0; i < fingerNames.Length; i++)
{
EditorGUILayout.BeginVertical(GUILayout.Width(SLIDER_WIDTH));
// 손가락 이름
GUILayout.Label(GetKoreanFingerName(fingerNames[i]),
EditorStyles.centeredGreyMiniLabel,
GUILayout.Width(SLIDER_WIDTH));
// 값 표시
SerializedProperty prop = serializedObject.FindProperty($"{prefix}{fingerNames[i]}Curl");
GUILayout.Label(prop.floatValue.ToString("F1"),
EditorStyles.centeredGreyMiniLabel,
GUILayout.Width(SLIDER_WIDTH));
// 세로 슬라이더를 중앙에 배치
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
prop.floatValue = GUILayout.VerticalSlider(
prop.floatValue,
1f,
-1f,
GUILayout.Width(SLIDER_WIDTH),
GUILayout.Height(SLIDER_HEIGHT)
);
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
if (i < fingerNames.Length - 1)
GUILayout.Space(SPACING);
}
EditorGUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
private string GetKoreanFingerName(string englishName)
{
switch (englishName)
{
case "Thumb": return "엄지";
case "Index": return "검지";
case "Middle": return "중지";
case "Ring": return "약지";
case "Pinky": return "새끼";
default: return englishName;
}
}
private void DrawSpreadSlider(string prefix)
{
SerializedProperty spreadProp = serializedObject.FindProperty($"{prefix}SpreadFingers");
EditorGUILayout.BeginHorizontal();
GUILayout.Space(15);
EditorGUILayout.LabelField("벌리기", GUILayout.Width(50));
spreadProp.floatValue = EditorGUILayout.Slider(spreadProp.floatValue, -1f, 1f);
GUILayout.Space(15);
EditorGUILayout.EndHorizontal();
}
private void DrawPresetButtons(FingerShapedController controller)
{
EditorGUILayout.LabelField("손 모양 프리셋", EditorStyles.boldLabel);
string[,] presets = {
{"가위", "바위", "보"},
{"브이", "검지", "초기화"}
};
for (int row = 0; row < 2; row++)
{
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace(); // 왼쪽 여백 추가
for (int col = 0; col < 3; col++)
{
if (GUILayout.Button(presets[row, col], GUILayout.Height(30), GUILayout.Width(100)))
{
ApplyPreset(controller, presets[row, col]);
}
if (col < 2) // 마지막 버튼 이전까지만 간격 추가
{
GUILayout.Space(10);
}
}
GUILayout.FlexibleSpace(); // 오른쪽 여백 추가
EditorGUILayout.EndHorizontal();
if (row < 1) // 행 사이 간격
{
GUILayout.Space(5);
}
}
}
private void ResetHandValues(string prefix)
{
string[] props = { "ThumbCurl", "IndexCurl", "MiddleCurl", "RingCurl", "PinkyCurl", "SpreadFingers" };
foreach (var prop in props)
{
serializedObject.FindProperty($"{prefix}{prop}").floatValue = 0f;
}
}
private void ApplyPreset(FingerShapedController controller, string presetName)
{
// 프리셋 적용 시 양손 모두 활성화
if (!controller.enabled)
{
controller.enabled = true;
}
switch (presetName)
{
case "가위":
SetPreset(controller, 1f, 1f, -1f, -1f, -1f, 0.3f);
break;
case "바위":
SetPreset(controller, -1f, -1f, -1f, -1f, -1f, 0f);
break;
case "보":
SetPreset(controller, 1f, 1f, 1f, 1f, 1f, 1f);
break;
case "브이":
SetPreset(controller, -1f, 1f, 1f, -1f, -1f, 1f);
break;
case "검지":
SetPreset(controller, -1f, 1f, -1f, -1f, -1f, 0f);
break;
case "초기화":
SetPreset(controller, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f);
break;
}
}
private void SetPreset(FingerShapedController controller, float thumb, float index,
float middle, float ring, float pinky, float spread)
{
// 왼손이 활성화된 경우에만 왼손 값 설정
if (controller.leftHandEnabled)
{
controller.leftThumbCurl = thumb;
controller.leftIndexCurl = index;
controller.leftMiddleCurl = middle;
controller.leftRingCurl = ring;
controller.leftPinkyCurl = pinky;
controller.leftSpreadFingers = spread;
}
// 오른손이 활성화된 경우에만 오른손 값 설정
if (controller.rightHandEnabled)
{
controller.rightThumbCurl = thumb;
controller.rightIndexCurl = index;
controller.rightMiddleCurl = middle;
controller.rightRingCurl = ring;
controller.rightPinkyCurl = pinky;
controller.rightSpreadFingers = spread;
}
EditorUtility.SetDirty(controller);
}
}