Fix : 에디터 ui 수정
This commit is contained in:
parent
657ca3d236
commit
595aa5f71f
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
@ -131,6 +132,7 @@ namespace KindRetargeting.Remote
|
||||
string property = json["property"]?.ToString();
|
||||
float value = json["value"]?.Value<float>() ?? 0f;
|
||||
UpdateValue(charId, property, value);
|
||||
BroadcastValueChanged(charId, property, value);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -164,6 +166,20 @@ namespace KindRetargeting.Remote
|
||||
}
|
||||
break;
|
||||
|
||||
case "autoHipsOffset":
|
||||
{
|
||||
string charId = json["characterId"]?.ToString();
|
||||
AutoHipsOffset(charId);
|
||||
}
|
||||
break;
|
||||
|
||||
case "autoCalibrateAll":
|
||||
{
|
||||
string charId = json["characterId"]?.ToString();
|
||||
AutoCalibrateAll(charId);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.LogWarning($"[RetargetingRemote] 알 수 없는 액션: {action}");
|
||||
break;
|
||||
@ -574,6 +590,7 @@ namespace KindRetargeting.Remote
|
||||
handPose.rightSpreadFingers = spread;
|
||||
}
|
||||
|
||||
SendCharacterData(characterId);
|
||||
SendStatus(true, $"{presetName} 프리셋 적용됨");
|
||||
}
|
||||
|
||||
@ -612,6 +629,93 @@ namespace KindRetargeting.Remote
|
||||
SendStatus(true, "정면 캘리브레이션 완료");
|
||||
}
|
||||
|
||||
private void AutoHipsOffset(string characterId)
|
||||
{
|
||||
var script = FindCharacter(characterId);
|
||||
if (script == null) return;
|
||||
|
||||
float offset = CalculateHipsOffsetFromLegDifference(script);
|
||||
SetPrivateField(script, "hipsOffsetY", offset);
|
||||
script.SaveSettings();
|
||||
|
||||
SendCharacterData(characterId);
|
||||
SendStatus(true, $"다리 길이 자동 보정 완료: hipsOffsetY={offset:F4}");
|
||||
}
|
||||
|
||||
private void AutoCalibrateAll(string characterId)
|
||||
{
|
||||
var script = FindCharacter(characterId);
|
||||
if (script == null) return;
|
||||
|
||||
Animator source = script.sourceAnimator;
|
||||
Animator targetAnim = script.targetAnimator;
|
||||
if (source == null || targetAnim == null || !source.isHuman || !targetAnim.isHuman)
|
||||
{
|
||||
SendStatus(false, "소스/타겟 Animator가 없거나 Humanoid가 아닙니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1: 크기 초기화 + 힙 오프셋 계산
|
||||
script.ResetScale();
|
||||
SetPrivateField(script, "avatarScale", 1f);
|
||||
SetPrivateField(script, "hipsOffsetY", CalculateHipsOffsetFromLegDifference(script));
|
||||
|
||||
// Step 2: 1프레임 후 목 높이 비율로 크기 조정
|
||||
StartCoroutine(AutoCalibrateCoroutine(script, characterId));
|
||||
}
|
||||
|
||||
private IEnumerator AutoCalibrateCoroutine(CustomRetargetingScript script, string characterId)
|
||||
{
|
||||
yield return null; // 1프레임 대기
|
||||
|
||||
Animator source = script.sourceAnimator;
|
||||
Animator targetAnim = script.targetAnimator;
|
||||
|
||||
Transform sourceNeck = source.GetBoneTransform(HumanBodyBones.Neck);
|
||||
Transform targetNeck = targetAnim.GetBoneTransform(HumanBodyBones.Neck);
|
||||
if (sourceNeck == null || targetNeck == null)
|
||||
{
|
||||
SendStatus(false, "목 본을 찾을 수 없습니다.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
float scaleRatio = Mathf.Clamp(sourceNeck.position.y / Mathf.Max(targetNeck.position.y, 0.01f), 0.1f, 3f);
|
||||
script.SetAvatarScale(scaleRatio);
|
||||
SetPrivateField(script, "avatarScale", scaleRatio);
|
||||
|
||||
yield return null; // 1프레임 대기
|
||||
|
||||
// Step 3: 힙 오프셋 재계산 + 머리 정면 캘리브레이션
|
||||
SetPrivateField(script, "hipsOffsetY", CalculateHipsOffsetFromLegDifference(script));
|
||||
script.CalibrateHeadToForward();
|
||||
script.SaveSettings();
|
||||
|
||||
SendCharacterData(characterId);
|
||||
SendStatus(true, $"전체 자동 보정 완료: avatarScale={scaleRatio:F3}");
|
||||
}
|
||||
|
||||
private float CalculateHipsOffsetFromLegDifference(CustomRetargetingScript script)
|
||||
{
|
||||
Animator source = script.sourceAnimator;
|
||||
Animator targetAnim = script.targetAnimator;
|
||||
if (source == null || targetAnim == null) return 0f;
|
||||
|
||||
float sourceLeg = GetLegLength(source);
|
||||
float targetLeg = GetLegLength(targetAnim);
|
||||
if (sourceLeg < 0.01f || targetLeg < 0.01f) return 0f;
|
||||
|
||||
return targetLeg - sourceLeg;
|
||||
}
|
||||
|
||||
private float GetLegLength(Animator animator)
|
||||
{
|
||||
Transform upper = animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg);
|
||||
Transform lower = animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg);
|
||||
Transform foot = animator.GetBoneTransform(HumanBodyBones.LeftFoot);
|
||||
if (upper == null || lower == null || foot == null) return 0f;
|
||||
return Vector3.Distance(upper.position, lower.position) + Vector3.Distance(lower.position, foot.position);
|
||||
}
|
||||
|
||||
private CustomRetargetingScript FindCharacter(string characterId)
|
||||
{
|
||||
foreach (var script in registeredCharacters)
|
||||
@ -624,6 +728,19 @@ namespace KindRetargeting.Remote
|
||||
return null;
|
||||
}
|
||||
|
||||
private void BroadcastValueChanged(string characterId, string property, float value)
|
||||
{
|
||||
var response = new
|
||||
{
|
||||
type = "valueChanged",
|
||||
characterId = characterId,
|
||||
property = property,
|
||||
value = value
|
||||
};
|
||||
|
||||
wsServer?.Broadcast(JsonConvert.SerializeObject(response));
|
||||
}
|
||||
|
||||
private void SendStatus(bool success, string message)
|
||||
{
|
||||
var response = new
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user