242 lines
8.7 KiB
C#
242 lines
8.7 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using UniHumanoid;
|
|
|
|
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();
|
|
}
|
|
|
|
public void SetTPose(Animator animator)
|
|
{
|
|
if (animator == null || animator.avatar == null)
|
|
return;
|
|
|
|
Avatar avatar = animator.avatar;
|
|
Transform transform = animator.transform;
|
|
|
|
// HumanPoseClip에 저장된 T-포즈 데이터를 로드하여 적용
|
|
var humanPoseClip = Resources.Load<HumanPoseClip>(HumanPoseClip.TPoseResourcePath);
|
|
if (humanPoseClip != null)
|
|
{
|
|
var pose = humanPoseClip.GetPose();
|
|
HumanPoseTransfer.SetPose(avatar, transform, pose);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("T-Pose 데이터가 존재하지 않습니다.");
|
|
}
|
|
}
|
|
private void CreateTargets()
|
|
{
|
|
Animator animator = GetComponent<Animator>();
|
|
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<GameObject> children = new List<GameObject>();
|
|
for (int i = 0; i < parent.childCount; i++)
|
|
{
|
|
children.Add(parent.GetChild(i).gameObject);
|
|
}
|
|
return children.ToArray();
|
|
}
|
|
}
|
|
} |