Fix : 머리 회전 기능 업데이트
This commit is contained in:
parent
580b64894c
commit
98676d49db
@ -108,6 +108,11 @@ namespace KindRetargeting
|
||||
[Header("발목 높이 설정")]
|
||||
[SerializeField] public float minimumAnkleHeight = 0.2f; // 수동 설정용 최소 발목 높이
|
||||
|
||||
[Header("머리 회전 오프셋")]
|
||||
[SerializeField, Range(-180f, 180f)] public float headRotationOffsetX = 0f; // 머리 좌우 기울기 (Roll)
|
||||
[SerializeField, Range(-180f, 180f)] public float headRotationOffsetY = 0f; // 머리 좌우 회전 (Yaw)
|
||||
[SerializeField, Range(-180f, 180f)] public float headRotationOffsetZ = 0f; // 머리 상하 회전 (Pitch)
|
||||
|
||||
[Header("설정 저장/로드")]
|
||||
[SerializeField] private string settingsFolderName = "RetargetingSettings";
|
||||
|
||||
@ -171,6 +176,10 @@ namespace KindRetargeting
|
||||
public List<MuscleCalibrationData> sourceMuscleCalibrationCache;
|
||||
// 의자 앉기 높이 오프셋 (LimbWeightController)
|
||||
public float chairSeatHeightOffset;
|
||||
// 머리 회전 오프셋
|
||||
public float headRotationOffsetX;
|
||||
public float headRotationOffsetY;
|
||||
public float headRotationOffsetZ;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
@ -685,6 +694,9 @@ namespace KindRetargeting
|
||||
fingerCloseRotationsCache = fingerCloseCache,
|
||||
sourceMuscleCalibrationCache = muscleCalibrationCache,
|
||||
chairSeatHeightOffset = chairOffset,
|
||||
headRotationOffsetX = headRotationOffsetX,
|
||||
headRotationOffsetY = headRotationOffsetY,
|
||||
headRotationOffsetZ = headRotationOffsetZ,
|
||||
};
|
||||
|
||||
string json = JsonUtility.ToJson(settings, true);
|
||||
@ -785,6 +797,11 @@ namespace KindRetargeting
|
||||
limbController.chairSeatHeightOffset = settings.chairSeatHeightOffset;
|
||||
}
|
||||
|
||||
// 머리 회전 오프셋 로드
|
||||
headRotationOffsetX = settings.headRotationOffsetX;
|
||||
headRotationOffsetY = settings.headRotationOffsetY;
|
||||
headRotationOffsetZ = settings.headRotationOffsetZ;
|
||||
|
||||
//너무 자주 출력되어서 주석처리
|
||||
//Debug.Log($"설정을 로드했습니다: {filePath}");
|
||||
}
|
||||
@ -1356,6 +1373,36 @@ namespace KindRetargeting
|
||||
previousScale = avatarScale;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LateUpdate에서 머리 회전 오프셋을 적용합니다 (IK 이후 실행).
|
||||
/// </summary>
|
||||
void LateUpdate()
|
||||
{
|
||||
ApplyHeadRotationOffset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 머리 본에 회전 오프셋을 적용합니다.
|
||||
/// </summary>
|
||||
private void ApplyHeadRotationOffset()
|
||||
{
|
||||
if (targetAnimator == null) return;
|
||||
|
||||
// 머리 본 가져오기
|
||||
Transform headBone = targetAnimator.GetBoneTransform(HumanBodyBones.Head);
|
||||
if (headBone == null) return;
|
||||
|
||||
// 오프셋이 모두 0이면 스킵
|
||||
if (Mathf.Approximately(headRotationOffsetX, 0f) &&
|
||||
Mathf.Approximately(headRotationOffsetY, 0f) &&
|
||||
Mathf.Approximately(headRotationOffsetZ, 0f))
|
||||
return;
|
||||
|
||||
// 오프셋 적용 (로컬 회전에 오일러 각도 추가)
|
||||
Quaternion offsetRotation = Quaternion.Euler(headRotationOffsetX, headRotationOffsetY, headRotationOffsetZ);
|
||||
headBone.localRotation *= offsetRotation;
|
||||
}
|
||||
/// <summary>
|
||||
/// 머슬 데이터를 사용하여 손가락 포즈를 복제합니다.
|
||||
/// SetHumanPose가 모든 본에 영향을 미치므로, 손가락을 제외한 모든 본의 Transform을 저장하고 복원합니다.
|
||||
|
||||
@ -27,6 +27,7 @@ public class RetargetingControlWindow : EditorWindow
|
||||
private Dictionary<int, bool> rightHandFoldouts = new Dictionary<int, bool>();
|
||||
private Dictionary<int, bool> headFoldouts = new Dictionary<int, bool>();
|
||||
private Dictionary<int, bool> propControlFoldouts = new Dictionary<int, bool>();
|
||||
private Dictionary<int, bool> headRotationFoldouts = new Dictionary<int, bool>();
|
||||
|
||||
private bool isDirty = false;
|
||||
private double lastUpdateTime;
|
||||
@ -233,6 +234,7 @@ public class RetargetingControlWindow : EditorWindow
|
||||
if (!rightHandFoldouts.ContainsKey(instanceID)) rightHandFoldouts[instanceID] = false;
|
||||
if (!headFoldouts.ContainsKey(instanceID)) headFoldouts[instanceID] = false;
|
||||
if (!propControlFoldouts.ContainsKey(instanceID)) propControlFoldouts[instanceID] = false;
|
||||
if (!headRotationFoldouts.ContainsKey(instanceID)) headRotationFoldouts[instanceID] = false;
|
||||
|
||||
SerializedObject serializedObject = new SerializedObject(script);
|
||||
|
||||
@ -387,6 +389,15 @@ public class RetargetingControlWindow : EditorWindow
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// 머리 회전 오프셋 설정 섹션
|
||||
headRotationFoldouts[instanceID] = EditorGUILayout.Foldout(headRotationFoldouts[instanceID], "머리 회전 오프셋", true);
|
||||
if (headRotationFoldouts[instanceID])
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
DrawHeadRotationSettings(serializedObject);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// 프랍 컨트롤 설정
|
||||
propControlFoldouts[instanceID] = EditorGUILayout.Foldout(propControlFoldouts[instanceID], "프랍 설정", true);
|
||||
if (propControlFoldouts[instanceID])
|
||||
@ -1114,6 +1125,39 @@ public class RetargetingControlWindow : EditorWindow
|
||||
}
|
||||
}
|
||||
|
||||
// 머리 회전 오프셋 UI 그리기 함수
|
||||
private void DrawHeadRotationSettings(SerializedObject serializedObject)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var headRotationXProp = serializedObject.FindProperty("headRotationOffsetX");
|
||||
var headRotationYProp = serializedObject.FindProperty("headRotationOffsetY");
|
||||
var headRotationZProp = serializedObject.FindProperty("headRotationOffsetZ");
|
||||
|
||||
EditorGUILayout.Slider(headRotationXProp, -180f, 180f,
|
||||
new GUIContent("X (Roll) - 좌우 기울기", "머리를 좌우로 기울입니다"));
|
||||
EditorGUILayout.Slider(headRotationYProp, -180f, 180f,
|
||||
new GUIContent("Y (Yaw) - 좌우 회전", "머리를 좌우로 회전합니다"));
|
||||
EditorGUILayout.Slider(headRotationZProp, -180f, 180f,
|
||||
new GUIContent("Z (Pitch) - 상하 회전", "머리를 상하로 회전합니다"));
|
||||
|
||||
// 초기화 버튼
|
||||
EditorGUILayout.Space(5);
|
||||
if (GUILayout.Button("회전 초기화", GUILayout.Height(25)))
|
||||
{
|
||||
headRotationXProp.floatValue = 0f;
|
||||
headRotationYProp.floatValue = 0f;
|
||||
headRotationZProp.floatValue = 0f;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(serializedObject.targetObject);
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
// 창이 포커스를 얻거나 잃을 때 리페인트
|
||||
private void OnFocus()
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user