Fix : 의자 높이 간의 조절 기능

This commit is contained in:
qsxft258@gmail.com 2025-08-29 14:45:09 +09:00
parent 7407760df3
commit 5915440f39
4 changed files with 96 additions and 6 deletions

View File

@ -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;
// 힙 회전 동기화 (회전 오프셋 적용)

View File

@ -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)

View File

@ -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();

View File

@ -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<PropTypeController>();
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; // 의자가 없을 때는 기본 가중치
}
}
}
}