using UnityEngine; using System.Collections.Generic; namespace KindRetargeting { public class PropLocationController : MonoBehaviour { // 캐시된 타겟과 오프셋 Transform [System.Serializable] public class TargetOffset { public Transform target; public Transform offset; } [SerializeField] private TargetOffset leftHandTargetOffset; [SerializeField] private TargetOffset rightHandTargetOffset; [SerializeField] private TargetOffset headTargetOffset; private void Start() { CreateTargets(); } private void CreateTargets() { Animator animator = GetComponent(); KindRetargeting.CustomRetargetingScript.SetTPose(animator); // 왼손 타겟 및 오프셋 설정 Transform leftHandBone = animator.GetBoneTransform(HumanBodyBones.LeftHand); if (leftHandBone != null) { leftHandTargetOffset = new TargetOffset(); GameObject leftTarget = new GameObject("Left_Hand_Target"); leftTarget.transform.parent = leftHandBone; // 왼손 본에 직접 부모 설정 leftHandTargetOffset.target = leftTarget.transform; leftTarget.transform.position = leftHandBone.position + new Vector3(-0.039f, -0.022f, 0f); leftTarget.transform.rotation = Quaternion.Euler( 90f, 0f, 0f); GameObject leftOffset = new GameObject("Left_Hand_Offset"); leftOffset.transform.parent = leftTarget.transform; leftHandTargetOffset.offset = leftOffset.transform; // 로컬 포지션과 로테이션 설정 leftHandTargetOffset.offset.localPosition = Vector3.zero; leftHandTargetOffset.offset.localRotation = Quaternion.identity; } // 오른손 타겟 및 오프셋 설정 Transform rightHandBone = animator.GetBoneTransform(HumanBodyBones.RightHand); if (rightHandBone != null) { rightHandTargetOffset = new TargetOffset(); GameObject rightTarget = new GameObject("Right_Hand_Target"); rightTarget.transform.parent = rightHandBone; // 오른손 본에 직접 부모 설정 rightHandTargetOffset.target = rightTarget.transform; rightTarget.transform.position = rightHandBone.position + new Vector3(0.039f, -0.022f, 0f); rightTarget.transform.rotation = Quaternion.Euler(90f, 0f, 0f); GameObject rightOffset = new GameObject("Right_Hand_Offset"); rightOffset.transform.parent = rightTarget.transform; rightHandTargetOffset.offset = rightOffset.transform; // 로컬 포지션과 로테이션 설정 rightHandTargetOffset.offset.localPosition = Vector3.zero; rightHandTargetOffset.offset.localRotation = Quaternion.identity; } // 머리 타겟 및 오프셋 설정 Transform headBone = animator.GetBoneTransform(HumanBodyBones.Head); if (headBone != null) { headTargetOffset = new TargetOffset(); GameObject headTarget = new GameObject("Head_Target"); headTarget.transform.parent = headBone; // 머리 본에 직접 부모 설정 headTargetOffset.target = headTarget.transform; headTarget.transform.position = headBone.position + new Vector3(0f, 0.16f, 0f); headTarget.transform.rotation = Quaternion.Euler(0f, 0f, 0f); GameObject headOffset = new GameObject("Head_Offset"); headOffset.transform.parent = headTarget.transform; headTargetOffset.offset = headOffset.transform; // 기본 오프셋 설정 headTargetOffset.offset.localPosition = Vector3.zero; headTargetOffset.offset.localRotation = Quaternion.identity; } animator.enabled = true; } public void MoveToHead(GameObject targetObject) { if (headTargetOffset?.offset == null) { Debug.LogError("머리 타겟이 할당되지 않았습니다!"); return; } if (targetObject != null) { targetObject.transform.SetParent(headTargetOffset.offset); targetObject.transform.localPosition = Vector3.zero; targetObject.transform.localRotation = Quaternion.identity; } } public void MoveToLeftHand(GameObject targetObject) { if (leftHandTargetOffset?.offset == null) { Debug.LogError("왼손 타겟이 할당되지 않았습니다!"); return; } if (targetObject != null) { targetObject.transform.SetParent(leftHandTargetOffset.offset); targetObject.transform.localPosition = Vector3.zero; targetObject.transform.localRotation = Quaternion.identity; } } public void MoveToRightHand(GameObject targetObject) { if (rightHandTargetOffset?.offset == null) { Debug.LogError("오른손 타겟이 할당되지 않았습니다!"); return; } if (targetObject != null) { targetObject.transform.SetParent(rightHandTargetOffset.offset); targetObject.transform.localPosition = Vector3.zero; targetObject.transform.localRotation = Quaternion.identity; } } public void DetachProp(GameObject targetObject) { if (targetObject != null) { targetObject.transform.SetParent(null); targetObject.transform.localScale = Vector3.one; } else { Debug.LogWarning("해제할 오브젝트가 없습니다."); } } // 에디터에서 사용할 메서드들 #if UNITY_EDITOR public void MoveToHead() { MoveToHead(UnityEditor.Selection.activeGameObject); } public void MoveToLeftHand() { MoveToLeftHand(UnityEditor.Selection.activeGameObject); } public void MoveToRightHand() { MoveToRightHand(UnityEditor.Selection.activeGameObject); } public void DetachProp() { DetachProp(UnityEditor.Selection.activeGameObject); } #endif // 오프셋 getter 메서드들 추가 public Transform GetLeftHandOffset() { return leftHandTargetOffset?.offset; } public Transform GetRightHandOffset() { return rightHandTargetOffset?.offset; } public Transform GetHeadOffset() { return headTargetOffset?.offset; } public GameObject[] GetHeadProps() { if (headTargetOffset?.offset == null) return new GameObject[0]; return GetChildObjects(headTargetOffset.offset); } public GameObject[] GetLeftHandProps() { if (leftHandTargetOffset?.offset == null) return new GameObject[0]; return GetChildObjects(leftHandTargetOffset.offset); } public GameObject[] GetRightHandProps() { if (rightHandTargetOffset?.offset == null) return new GameObject[0]; return GetChildObjects(rightHandTargetOffset.offset); } private GameObject[] GetChildObjects(Transform parent) { List children = new List(); for (int i = 0; i < parent.childCount; i++) { children.Add(parent.GetChild(i).gameObject); } return children.ToArray(); } } }