From 5915440f397777463444f531814011d30996e9d8 Mon Sep 17 00:00:00 2001 From: "qsxft258@gmail.com" Date: Fri, 29 Aug 2025 14:45:09 +0900 Subject: [PATCH] =?UTF-8?q?Fix=20:=20=EC=9D=98=EC=9E=90=20=EB=86=92?= =?UTF-8?q?=EC=9D=B4=20=EA=B0=84=EC=9D=98=20=EC=A1=B0=EC=A0=88=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomRetargetingScript.cs | 6 +- .../Editor/LimbWeightControllerEditor.cs | 24 ++++++++ .../Editor/RetargetingControlWindow.cs | 12 ++++ .../KindRetargeting/LimbWeightController.cs | 60 +++++++++++++++++-- 4 files changed, 96 insertions(+), 6 deletions(-) diff --git a/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs b/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs index c8df0e0b..c6eb325e 100644 --- a/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs +++ b/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs @@ -33,6 +33,7 @@ namespace KindRetargeting private float hipsWeight = 0f; // 힙의 위치를 위아래로 보정하는 가중치 [HideInInspector] public float HipsWeightOffset = 1f; + [HideInInspector] public float HipsHeightAdjustment = 0f; // 허리 높이 절대 조정값 // HumanPoseHandler를 이용하여 원본 및 대상 아바타의 포즈를 관리 private HumanPoseHandler sourcePoseHandler; @@ -707,10 +708,11 @@ namespace KindRetargeting if (sourceHips != null && targetHips != null) { - // 힙 위치 동기화 + 힙 위치 보정 적용 + 바닥 높이 적용용 + // 힙 위치 동기화 + 힙 위치 보정 적용 + 바닥 높이 적용 + 의자 높이 조정 Vector3 adjustedPosition = sourceHips.position; adjustedPosition.y += hipsWeight * HipsWeightOffset; // 기존 힙 높이 조정 - adjustedPosition.y += floorHeight; // 바닥 높이 조정 추가 + adjustedPosition.y += floorHeight; // 바닥 높이 조정 + adjustedPosition.y += HipsHeightAdjustment; // 의자 기반 절대 높이 조정 추가 targetHips.position = adjustedPosition; // 힙 회전 동기화 (회전 오프셋 적용) diff --git a/Assets/Scripts/KindRetargeting/Editor/LimbWeightControllerEditor.cs b/Assets/Scripts/KindRetargeting/Editor/LimbWeightControllerEditor.cs index 8229cfc4..a871598a 100644 --- a/Assets/Scripts/KindRetargeting/Editor/LimbWeightControllerEditor.cs +++ b/Assets/Scripts/KindRetargeting/Editor/LimbWeightControllerEditor.cs @@ -12,6 +12,8 @@ namespace KindRetargeting SerializedProperty middleWeightMultiplier; SerializedProperty hipsMinDistance; SerializedProperty hipsMaxDistance; + SerializedProperty useFixedChairGap; + SerializedProperty chairHipsFixedGap; SerializedProperty props; SerializedProperty characterRoot; SerializedProperty groundHipsMinHeight; @@ -24,6 +26,7 @@ namespace KindRetargeting private bool showDistanceSettings = true; private bool showWeightSettings = true; private bool showHipsSettings = true; + private bool showChairHeightSettings = true; private bool showReferences = true; private bool showGroundHipsSettings = true; private bool showFootHeightSettings = true; @@ -42,6 +45,8 @@ namespace KindRetargeting middleWeightMultiplier = serializedObject.FindProperty("middleWeightMultiplier"); hipsMinDistance = serializedObject.FindProperty("hipsMinDistance"); hipsMaxDistance = serializedObject.FindProperty("hipsMaxDistance"); + useFixedChairGap = serializedObject.FindProperty("useFixedChairGap"); + chairHipsFixedGap = serializedObject.FindProperty("chairHipsFixedGap"); props = serializedObject.FindProperty("props"); characterRoot = serializedObject.FindProperty("characterRoot"); groundHipsMinHeight = serializedObject.FindProperty("groundHipsMinHeight"); @@ -126,6 +131,25 @@ namespace KindRetargeting EditorGUI.indentLevel--; } + EditorGUILayout.Space(5); + showChairHeightSettings = EditorGUILayout.Foldout(showChairHeightSettings, "의자 거리 기반 허리 높이 설정", true); + if (showChairHeightSettings) + { + EditorGUI.indentLevel++; + + EditorGUILayout.PropertyField(useFixedChairGap, new GUIContent("고정 간격 사용")); + + if (useFixedChairGap.boolValue) + { + EditorGUILayout.PropertyField(chairHipsFixedGap, new GUIContent("의자-허리 고정 간격")); + + EditorGUILayout.Space(5); + EditorGUILayout.HelpBox("의자가 가까워지면 허리 높이가 의자 높이 + 고정 간격으로 자동 조절됩니다.", MessageType.Info); + } + + EditorGUI.indentLevel--; + } + EditorGUILayout.Space(5); showGroundHipsSettings = EditorGUILayout.Foldout(showGroundHipsSettings, "바닥 기준 히프 보정 설정", true); if (showGroundHipsSettings) diff --git a/Assets/Scripts/KindRetargeting/Editor/RetargetingControlWindow.cs b/Assets/Scripts/KindRetargeting/Editor/RetargetingControlWindow.cs index 60f223ec..0e7a8306 100644 --- a/Assets/Scripts/KindRetargeting/Editor/RetargetingControlWindow.cs +++ b/Assets/Scripts/KindRetargeting/Editor/RetargetingControlWindow.cs @@ -912,6 +912,18 @@ public class RetargetingControlWindow : EditorWindow EditorGUILayout.Space(5); + // 의자 허리 고정 간격 설정 추가 + var useFixedChairGap = serializedLimb.FindProperty("useFixedChairGap"); + var chairHipsFixedGap = serializedLimb.FindProperty("chairHipsFixedGap"); + + EditorGUILayout.PropertyField(useFixedChairGap, new GUIContent("의자 고정 간격 사용")); + if (useFixedChairGap.boolValue) + { + EditorGUILayout.PropertyField(chairHipsFixedGap, new GUIContent("의자-허리 고정 간격")); + } + + EditorGUILayout.Space(5); + // 바닥 기준 히프 높이 범위 EditorGUILayout.LabelField("바닥과 허리 높이에 의한 블렌딩 (가중치 0 -> 1)"); EditorGUILayout.BeginHorizontal(); diff --git a/Assets/Scripts/KindRetargeting/LimbWeightController.cs b/Assets/Scripts/KindRetargeting/LimbWeightController.cs index 6ea13eb4..de577dd7 100644 --- a/Assets/Scripts/KindRetargeting/LimbWeightController.cs +++ b/Assets/Scripts/KindRetargeting/LimbWeightController.cs @@ -20,6 +20,10 @@ namespace KindRetargeting [SerializeField, Range(0.1f, 1f)] public float hipsMinDistance = 0.2f; // 최소 거리 (가중치 1) [SerializeField, Range(0.1f, 1f)] public float hipsMaxDistance = 0.6f; // 최대 거리 (가중치 0) + [Header("의자 거리 기반 허리 높이 설정")] + [SerializeField] public bool useFixedChairGap = true; // 고정 간격 사용 여부 + [SerializeField, Range(0.1f, 1f)] public float chairHipsFixedGap = 0.2f; // 의자와 허리 간 고정 간격 + [Header("바닥 기준 히프 보정")] [SerializeField, Range(0.3f, 1f)] public float groundHipsMinHeight = 0f; // 최소 높이 (가중치 0) [SerializeField, Range(0.5f, 1.5f)] public float groundHipsMaxHeight = 0.5f; // 최대 높이 (가중치 1) @@ -296,19 +300,67 @@ namespace KindRetargeting Transform hipsTransform = crs.sourceAnimator.GetBoneTransform(HumanBodyBones.Hips); if (hipsTransform != null && props != null) { + float minChairHeight = float.MaxValue; float minDistance = float.MaxValue; + bool chairFound = false; + foreach (Transform prop in props) { PropTypeController ptc = prop.GetComponent(); if (ptc != null && ptc.propType == EnumsList.PropType.Chair) { - float distance = Vector3.Distance(hipsTransform.position, prop.childCount > 0 ? prop.GetChild(0).position : prop.position); - minDistance = Mathf.Min(minDistance, distance); + Vector3 chairPosition = prop.childCount > 0 ? prop.GetChild(0).position : prop.position; + float chairY = chairPosition.y; + float distance = Vector3.Distance(hipsTransform.position, chairPosition); + + // 의자가 가까운 거리에 있을 때만 높이 조절 + if (distance <= hipsMaxDistance) + { + minChairHeight = Mathf.Min(minChairHeight, chairY); + minDistance = Mathf.Min(minDistance, distance); + chairFound = true; + } } } - float t = Mathf.Clamp01((minDistance - hipsMinDistance) / (hipsMaxDistance - hipsMinDistance)); - hipsWeights[0] = t; // 직접 HipsWeightOffset 수정 대신 배열에 저장 + if (chairFound && useFixedChairGap) + { + // 목표 허리 높이 = 의자 높이 + 고정 간격 + float targetHipsHeight = minChairHeight + chairHipsFixedGap; + float currentHipsHeight = hipsTransform.position.y; + + // 허리 높이 조정값 계산 (절대값) + float heightAdjustment = targetHipsHeight - currentHipsHeight; + + // CustomRetargetingScript에 높이 조정값 전달 (가중치 대신 절대값) + if (crs != null) + { + crs.HipsHeightAdjustment = heightAdjustment; + } + + // 기존 가중치 시스템도 유지 (필요시) + float t = Mathf.Clamp01((minDistance - hipsMinDistance) / (hipsMaxDistance - hipsMinDistance)); + hipsWeights[0] = t; + } + else + { + // 의자가 없거나 멀 때는 조정 안 함 + if (crs != null) + { + crs.HipsHeightAdjustment = 0f; + } + + // 기존 가중치는 기본값으로 설정 + if (chairFound) + { + float t = Mathf.Clamp01((minDistance - hipsMinDistance) / (hipsMaxDistance - hipsMinDistance)); + hipsWeights[0] = t; + } + else + { + hipsWeights[0] = 1f; // 의자가 없을 때는 기본 가중치 + } + } } }