260 lines
8.7 KiB
C#
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);
|
|
}
|
|
} |