Refactor : ShoulderCorrectionFunction을 Serializable 모듈로 전환
- RequireComponent 6개 제거 (모듈화 준비) - ShoulderCorrectionFunction: MonoBehaviour → [Serializable] 클래스 - Start() → Initialize(Animator), Update() → OnUpdate() - CustomRetargetingScript에서 shoulderCorrection 필드로 소유 및 호출 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b0c967e1fd
commit
52d6960710
@ -9,12 +9,6 @@ namespace KindRetargeting
|
|||||||
/// 이 스크립트는 원본 아바타(Source)의 포즈 손가락 움직임을 대상 아바타(Target)에 리타게팅(Retargeting)합니다.
|
/// 이 스크립트는 원본 아바타(Source)의 포즈 손가락 움직임을 대상 아바타(Target)에 리타게팅(Retargeting)합니다.
|
||||||
/// 또한 IK 타겟을 생성하여 대상 아바타의 관절 움직임을 자연스럽게 조정합니다.
|
/// 또한 IK 타겟을 생성하여 대상 아바타의 관절 움직임을 자연스럽게 조정합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RequireComponent(typeof(LimbWeightController))]
|
|
||||||
[RequireComponent(typeof(ShoulderCorrectionFunction))]
|
|
||||||
[RequireComponent(typeof(TwoBoneIKSolver))]
|
|
||||||
[RequireComponent(typeof(FootGroundingController))]
|
|
||||||
[RequireComponent(typeof(PropLocationController))]
|
|
||||||
[RequireComponent(typeof(FingerShapedController))]
|
|
||||||
[DefaultExecutionOrder(1)]
|
[DefaultExecutionOrder(1)]
|
||||||
public class CustomRetargetingScript : MonoBehaviour
|
public class CustomRetargetingScript : MonoBehaviour
|
||||||
{
|
{
|
||||||
@ -101,6 +95,9 @@ namespace KindRetargeting
|
|||||||
[HideInInspector] public Vector3 tPoseHeadForward = Vector3.forward;
|
[HideInInspector] public Vector3 tPoseHeadForward = Vector3.forward;
|
||||||
[HideInInspector] public Vector3 tPoseHeadUp = Vector3.up;
|
[HideInInspector] public Vector3 tPoseHeadUp = Vector3.up;
|
||||||
|
|
||||||
|
[Header("어깨 보정")]
|
||||||
|
[SerializeField] public ShoulderCorrectionFunction shoulderCorrection = new ShoulderCorrectionFunction();
|
||||||
|
|
||||||
[Header("아바타 크기 조정")]
|
[Header("아바타 크기 조정")]
|
||||||
[SerializeField, Range(0.1f, 3f)] private float avatarScale = 1f;
|
[SerializeField, Range(0.1f, 3f)] private float avatarScale = 1f;
|
||||||
private float previousScale = 1f;
|
private float previousScale = 1f;
|
||||||
@ -324,6 +321,10 @@ namespace KindRetargeting
|
|||||||
Debug.LogWarning("[CustomRetargetingScript] 머리 본을 찾을 수 없습니다!");
|
Debug.LogWarning("[CustomRetargetingScript] 머리 본을 찾을 수 없습니다!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 어깨 보정 모듈 초기화
|
||||||
|
if (targetAnimator != null)
|
||||||
|
shoulderCorrection.Initialize(targetAnimator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -821,6 +822,9 @@ namespace KindRetargeting
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 어깨 보정 (기존 ExecutionOrder 3)
|
||||||
|
shoulderCorrection.OnUpdate();
|
||||||
|
|
||||||
// 스케일 변경 확인 및 적용
|
// 스케일 변경 확인 및 적용
|
||||||
if (!Mathf.Approximately(previousScale, avatarScale))
|
if (!Mathf.Approximately(previousScale, avatarScale))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,22 +2,20 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace KindRetargeting
|
namespace KindRetargeting
|
||||||
{
|
{
|
||||||
[DefaultExecutionOrder(3)]
|
[System.Serializable]
|
||||||
public class ShoulderCorrectionFunction : MonoBehaviour
|
public class ShoulderCorrectionFunction
|
||||||
{
|
{
|
||||||
private CustomRetargetingScript retargetingScript; // 소스 데이터를 가져올 리타게팅 스크립트
|
|
||||||
|
|
||||||
[Header("설정")]
|
[Header("설정")]
|
||||||
[Range(0f, 5f)]
|
[Range(0f, 5f)]
|
||||||
public float blendStrength = 2f; // 전체적인 보정 강도
|
public float blendStrength = 2f;
|
||||||
[Range(0f, 1f)]
|
[Range(0f, 1f)]
|
||||||
public float maxShoulderBlend = 0.7f; // 어깨에 최대로 전달될 수 있는 회전 비율
|
public float maxShoulderBlend = 0.7f;
|
||||||
public bool reverseLeftRotation = false; // 왼쪽 어깨 회전 방향 반전 설정
|
public bool reverseLeftRotation = false;
|
||||||
public bool reverseRightRotation = false; // 오른쪽 어깨 회전 방향 반전 설정
|
public bool reverseRightRotation = false;
|
||||||
|
|
||||||
[Header("높이 제한 설정")]
|
[Header("높이 제한 설정")]
|
||||||
public float maxHeightDifference = 0.8f; // 최대 높이 차이
|
public float maxHeightDifference = 0.8f;
|
||||||
public float minHeightDifference = -0.1f; // 최소 높이 차이 (이 값 이하에서는 보정하지 않음)
|
public float minHeightDifference = -0.1f;
|
||||||
|
|
||||||
[Header("보정 커브 설정")]
|
[Header("보정 커브 설정")]
|
||||||
public AnimationCurve shoulderCorrectionCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
public AnimationCurve shoulderCorrectionCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||||
@ -29,26 +27,24 @@ namespace KindRetargeting
|
|||||||
private Transform rightShoulder;
|
private Transform rightShoulder;
|
||||||
private Transform leftUpperArm;
|
private Transform leftUpperArm;
|
||||||
private Transform rightUpperArm;
|
private Transform rightUpperArm;
|
||||||
// 최적화: 팔꿈치(LowerArm) Transform 캐싱 추가
|
|
||||||
private Transform leftLowerArm;
|
private Transform leftLowerArm;
|
||||||
private Transform rightLowerArm;
|
private Transform rightLowerArm;
|
||||||
|
|
||||||
private void Start()
|
public void Initialize(Animator targetAnimator)
|
||||||
{
|
{
|
||||||
retargetingScript = GetComponent<CustomRetargetingScript>();
|
leftShoulder = targetAnimator.GetBoneTransform(HumanBodyBones.LeftShoulder);
|
||||||
|
rightShoulder = targetAnimator.GetBoneTransform(HumanBodyBones.RightShoulder);
|
||||||
leftShoulder = retargetingScript.targetAnimator.GetBoneTransform(HumanBodyBones.LeftShoulder);
|
leftUpperArm = targetAnimator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
|
||||||
rightShoulder = retargetingScript.targetAnimator.GetBoneTransform(HumanBodyBones.RightShoulder);
|
rightUpperArm = targetAnimator.GetBoneTransform(HumanBodyBones.RightUpperArm);
|
||||||
leftUpperArm = retargetingScript.targetAnimator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
|
leftLowerArm = targetAnimator.GetBoneTransform(HumanBodyBones.LeftLowerArm);
|
||||||
rightUpperArm = retargetingScript.targetAnimator.GetBoneTransform(HumanBodyBones.RightUpperArm);
|
rightLowerArm = targetAnimator.GetBoneTransform(HumanBodyBones.RightLowerArm);
|
||||||
// 최적화: 팔꿈치 Transform도 Start에서 캐싱
|
|
||||||
leftLowerArm = retargetingScript.targetAnimator.GetBoneTransform(HumanBodyBones.LeftLowerArm);
|
|
||||||
rightLowerArm = retargetingScript.targetAnimator.GetBoneTransform(HumanBodyBones.RightLowerArm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
public void OnUpdate()
|
||||||
{
|
{
|
||||||
// 왼쪽 어깨 보정 (최적화: 캐싱된 Transform 사용)
|
if (leftShoulder == null || rightShoulder == null) return;
|
||||||
|
|
||||||
|
// 왼쪽 어깨 보정
|
||||||
Vector3 leftElbowPos = leftLowerArm.position;
|
Vector3 leftElbowPos = leftLowerArm.position;
|
||||||
float leftHeightDiff = leftElbowPos.y - leftShoulder.position.y;
|
float leftHeightDiff = leftElbowPos.y - leftShoulder.position.y;
|
||||||
float leftRawBlend = Mathf.Clamp01(
|
float leftRawBlend = Mathf.Clamp01(
|
||||||
@ -56,7 +52,7 @@ namespace KindRetargeting
|
|||||||
);
|
);
|
||||||
leftBlendWeight = shoulderCorrectionCurve.Evaluate(leftRawBlend) * maxShoulderBlend;
|
leftBlendWeight = shoulderCorrectionCurve.Evaluate(leftRawBlend) * maxShoulderBlend;
|
||||||
|
|
||||||
// 오른쪽 어깨 보정 (최적화: 캐싱된 Transform 사용)
|
// 오른쪽 어깨 보정
|
||||||
Vector3 rightElbowPos = rightLowerArm.position;
|
Vector3 rightElbowPos = rightLowerArm.position;
|
||||||
float rightHeightDiff = rightElbowPos.y - rightShoulder.position.y;
|
float rightHeightDiff = rightElbowPos.y - rightShoulder.position.y;
|
||||||
float rightRawBlend = Mathf.Clamp01(
|
float rightRawBlend = Mathf.Clamp01(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user