Streamingle_URP/Assets/Scripts/KindRetargeting/Editor/FullBodyInverseKinematicsEditor.cs
user 4a49ecd772 Refactor: 배경/프랍 브라우저 IMGUI→UI Toolkit 전환 + USS 리디자인
- BackgroundSceneLoaderWindow: OnGUI → CreateGUI (Toolbar + ToolbarSearchField)
- PropBrowserWindow: OnGUI → CreateGUI (Toolbar + ToolbarSearchField)
- StreamingleCommon.uss: 브라우저 공통 스타일 추가 (그리드/리스트/뷰토글/액션바/상태바)
- excludeFromWeb 상태 새로고침 시 보존 수정
- 삭제된 배경 리소스 정리

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 01:55:48 +09:00

112 lines
4.6 KiB
C#

using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using KindRetargeting;
[CustomEditor(typeof(FullBodyInverseKinematics))]
public class FullBodyInverseKinematicsEditor : BaseRetargetingEditor
{
private const string CommonUssPath = "Assets/Scripts/Streamingle/StreamingleControl/Editor/UXML/StreamingleCommon.uss";
private SerializedProperty iterationsProp;
private SerializedProperty deltaThresholdProp;
private SerializedProperty[] limbProps;
private readonly string[] limbNames = { "왼팔", "오른팔", "왼다리", "오른다리" };
private readonly string[] limbPropNames = { "leftArm", "rightArm", "leftLeg", "rightLeg" };
protected override void OnEnable()
{
base.OnEnable();
iterationsProp = serializedObject.FindProperty("iterations");
deltaThresholdProp = serializedObject.FindProperty("deltaThreshold");
limbProps = new SerializedProperty[4];
for (int i = 0; i < 4; i++)
limbProps[i] = serializedObject.FindProperty(limbPropNames[i]);
}
public override VisualElement CreateInspectorGUI()
{
var root = new VisualElement();
var commonUss = AssetDatabase.LoadAssetAtPath<StyleSheet>(CommonUssPath);
if (commonUss != null) root.styleSheets.Add(commonUss);
// IK 기본 설정
var basicFoldout = new Foldout { text = "IK 기본 설정", value = true };
basicFoldout.Add(new PropertyField(iterationsProp, "반복 횟수"));
basicFoldout.Add(new PropertyField(deltaThresholdProp, "델타 임계값"));
root.Add(basicFoldout);
// 사지 설정
var limbFoldout = new Foldout { text = "사지 설정" };
for (int i = 0; i < 4; i++)
limbFoldout.Add(BuildLimbElement(i));
root.Add(limbFoldout);
return root;
}
private VisualElement BuildLimbElement(int index)
{
var container = new VisualElement();
container.style.backgroundColor = new Color(0, 0, 0, 0.1f);
container.style.borderTopLeftRadius = container.style.borderTopRightRadius =
container.style.borderBottomLeftRadius = container.style.borderBottomRightRadius = 4;
container.style.paddingTop = container.style.paddingBottom =
container.style.paddingLeft = container.style.paddingRight = 4;
container.style.marginBottom = 4;
if (index >= limbProps.Length || limbProps[index] == null)
{
container.Add(new HelpBox($"'{limbPropNames[index]}' 프로퍼티를 찾을 수 없습니다.", HelpBoxMessageType.Warning));
return container;
}
var foldout = new Foldout { text = limbNames[index] };
var enableIKProp = limbProps[index].FindPropertyRelative("enableIK");
if (enableIKProp == null) { container.Add(foldout); return container; }
foldout.Add(new PropertyField(enableIKProp, "IK 활성화"));
var ikSettings = new VisualElement { style = { marginTop = 4 } };
// 엔드 타겟
var endTargetProp = limbProps[index].FindPropertyRelative("endTarget");
if (endTargetProp != null)
{
ikSettings.Add(new PropertyField(endTargetProp.FindPropertyRelative("target"), "엔드 타겟"));
ikSettings.Add(new PropertyField(endTargetProp.FindPropertyRelative("weight"), "엔드 가중치"));
}
// 미들 타겟
var middleTargetProp = limbProps[index].FindPropertyRelative("middleTarget");
if (middleTargetProp != null)
{
ikSettings.Add(new PropertyField(middleTargetProp.FindPropertyRelative("target"), "미들 타겟"));
ikSettings.Add(new PropertyField(middleTargetProp.FindPropertyRelative("weight"), "미들 가중치"));
}
// 발목 타겟
var ankleTargetProp = limbProps[index].FindPropertyRelative("ankleTarget");
if (ankleTargetProp != null)
{
ikSettings.Add(new PropertyField(ankleTargetProp.FindPropertyRelative("target"), "발목 타겟"));
ikSettings.Add(new PropertyField(ankleTargetProp.FindPropertyRelative("weight"), "발목 가중치"));
}
foldout.Add(ikSettings);
// enableIK 토글에 따라 설정 표시/숨김
foldout.TrackPropertyValue(enableIKProp, prop =>
{
ikSettings.style.display = prop.boolValue ? DisplayStyle.Flex : DisplayStyle.None;
});
ikSettings.style.display = enableIKProp.boolValue ? DisplayStyle.Flex : DisplayStyle.None;
container.Add(foldout);
return container;
}
}