Modify: 야모 휴머노이드본 리네임 스크립트 업데이트
This commit is contained in:
parent
576410a0b9
commit
a759058db5
@ -25,6 +25,12 @@ public class RenameHumanoidBones : EditorWindow
|
||||
FindHumanoidBones();
|
||||
}
|
||||
|
||||
// 믹사모 네이밍으로 일괄 변경 버튼 추가
|
||||
if (GUILayout.Button("믹사모 네이밍으로 일괄 변경"))
|
||||
{
|
||||
RenameToMixamo();
|
||||
}
|
||||
|
||||
if (selectedAnimator == null)
|
||||
{
|
||||
GUILayout.Label("No valid Humanoid Animator selected.", EditorStyles.helpBox);
|
||||
@ -33,6 +39,27 @@ public class RenameHumanoidBones : EditorWindow
|
||||
|
||||
GUILayout.Label("Selected GameObject: " + selectedAnimator.gameObject.name, EditorStyles.boldLabel);
|
||||
|
||||
// T포즈 관련 버튼들 추가
|
||||
EditorGUILayout.Space();
|
||||
GUILayout.Label("T-Pose Functions", EditorStyles.boldLabel);
|
||||
|
||||
if (GUILayout.Button("Check T-Pose Conditions"))
|
||||
{
|
||||
CheckTPoseConditions();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Apply Perfect T-Pose"))
|
||||
{
|
||||
ApplyPerfectTPose();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Reset to Default Pose"))
|
||||
{
|
||||
ResetToDefaultPose();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (humanoidBones.Count > 0)
|
||||
{
|
||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(400));
|
||||
@ -124,4 +151,932 @@ public class RenameHumanoidBones : EditorWindow
|
||||
|
||||
Debug.Log("Bone renaming completed.");
|
||||
}
|
||||
|
||||
// T포즈 조건 검증
|
||||
private void CheckTPoseConditions()
|
||||
{
|
||||
if (selectedAnimator == null)
|
||||
{
|
||||
Debug.LogError("No valid Humanoid Animator selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("=== T-Pose Conditions Check ===");
|
||||
|
||||
// 1. 몸통 뼈대들의 World X축 좌표가 0인지 확인
|
||||
CheckBodyAlignment();
|
||||
|
||||
// 2. 팔 뼈대들의 World Z축 좌표가 동일한지 확인
|
||||
CheckArmAlignment();
|
||||
|
||||
// 3. 다리 뼈대들의 World X축 좌표가 동일한지 확인
|
||||
CheckLegAlignment();
|
||||
|
||||
Debug.Log("=== T-Pose Conditions Check Complete ===");
|
||||
}
|
||||
|
||||
private void CheckBodyAlignment()
|
||||
{
|
||||
Debug.Log("--- Body Alignment Check ---");
|
||||
|
||||
HumanBodyBones[] bodyBones = {
|
||||
HumanBodyBones.Hips,
|
||||
HumanBodyBones.Spine,
|
||||
HumanBodyBones.Chest,
|
||||
HumanBodyBones.UpperChest,
|
||||
HumanBodyBones.Neck,
|
||||
HumanBodyBones.Head
|
||||
};
|
||||
|
||||
float targetX = 0f;
|
||||
bool allAligned = true;
|
||||
|
||||
foreach (var boneType in bodyBones)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(boneType);
|
||||
if (bone != null)
|
||||
{
|
||||
float worldX = bone.position.x;
|
||||
float difference = Mathf.Abs(worldX - targetX);
|
||||
|
||||
Debug.Log($"{boneType}: World X = {worldX:F3} (Target: {targetX:F3}, Difference: {difference:F3})");
|
||||
|
||||
if (difference > 0.01f)
|
||||
{
|
||||
allAligned = false;
|
||||
Debug.LogWarning($" -> {boneType} is not aligned! Difference: {difference:F3}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allAligned)
|
||||
{
|
||||
Debug.Log("✓ Body bones are properly aligned on X-axis");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("✗ Body bones are NOT properly aligned on X-axis");
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckArmAlignment()
|
||||
{
|
||||
Debug.Log("--- Arm Alignment Check ---");
|
||||
|
||||
HumanBodyBones[] leftArmBones = {
|
||||
HumanBodyBones.LeftShoulder,
|
||||
HumanBodyBones.LeftUpperArm,
|
||||
HumanBodyBones.LeftLowerArm,
|
||||
HumanBodyBones.LeftHand
|
||||
};
|
||||
|
||||
HumanBodyBones[] rightArmBones = {
|
||||
HumanBodyBones.RightShoulder,
|
||||
HumanBodyBones.RightUpperArm,
|
||||
HumanBodyBones.RightLowerArm,
|
||||
HumanBodyBones.RightHand
|
||||
};
|
||||
|
||||
CheckSideArmAlignment("Left Arm", leftArmBones);
|
||||
CheckSideArmAlignment("Right Arm", rightArmBones);
|
||||
}
|
||||
|
||||
private void CheckSideArmAlignment(string sideName, HumanBodyBones[] armBones)
|
||||
{
|
||||
Debug.Log($"--- {sideName} Alignment Check ---");
|
||||
|
||||
float targetZ = 0f;
|
||||
bool firstBone = true;
|
||||
bool allAligned = true;
|
||||
|
||||
foreach (var boneType in armBones)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(boneType);
|
||||
if (bone != null)
|
||||
{
|
||||
float worldZ = bone.position.z;
|
||||
|
||||
if (firstBone)
|
||||
{
|
||||
targetZ = worldZ;
|
||||
firstBone = false;
|
||||
}
|
||||
|
||||
float difference = Mathf.Abs(worldZ - targetZ);
|
||||
|
||||
Debug.Log($"{boneType}: World Z = {worldZ:F3} (Target: {targetZ:F3}, Difference: {difference:F3})");
|
||||
|
||||
if (difference > 0.01f)
|
||||
{
|
||||
allAligned = false;
|
||||
Debug.LogWarning($" -> {boneType} is not aligned! Difference: {difference:F3}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allAligned)
|
||||
{
|
||||
Debug.Log($"✓ {sideName} bones are properly aligned on Z-axis");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"✗ {sideName} bones are NOT properly aligned on Z-axis");
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckLegAlignment()
|
||||
{
|
||||
Debug.Log("--- Leg Alignment Check ---");
|
||||
|
||||
HumanBodyBones[] leftLegBones = {
|
||||
HumanBodyBones.LeftUpperLeg,
|
||||
HumanBodyBones.LeftLowerLeg,
|
||||
HumanBodyBones.LeftFoot,
|
||||
HumanBodyBones.LeftToes
|
||||
};
|
||||
|
||||
HumanBodyBones[] rightLegBones = {
|
||||
HumanBodyBones.RightUpperLeg,
|
||||
HumanBodyBones.RightLowerLeg,
|
||||
HumanBodyBones.RightFoot,
|
||||
HumanBodyBones.RightToes
|
||||
};
|
||||
|
||||
CheckSideLegAlignment("Left Leg", leftLegBones);
|
||||
CheckSideLegAlignment("Right Leg", rightLegBones);
|
||||
}
|
||||
|
||||
private void CheckSideLegAlignment(string sideName, HumanBodyBones[] legBones)
|
||||
{
|
||||
Debug.Log($"--- {sideName} Alignment Check ---");
|
||||
|
||||
float targetX = 0f;
|
||||
bool firstBone = true;
|
||||
bool allAligned = true;
|
||||
|
||||
foreach (var boneType in legBones)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(boneType);
|
||||
if (bone != null)
|
||||
{
|
||||
float worldX = bone.position.x;
|
||||
|
||||
if (firstBone)
|
||||
{
|
||||
targetX = worldX;
|
||||
firstBone = false;
|
||||
}
|
||||
|
||||
float difference = Mathf.Abs(worldX - targetX);
|
||||
|
||||
Debug.Log($"{boneType}: World X = {worldX:F3} (Target: {targetX:F3}, Difference: {difference:F3})");
|
||||
|
||||
if (difference > 0.01f)
|
||||
{
|
||||
allAligned = false;
|
||||
Debug.LogWarning($" -> {boneType} is not aligned! Difference: {difference:F3}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allAligned)
|
||||
{
|
||||
Debug.Log($"✓ {sideName} bones are properly aligned on X-axis");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"✗ {sideName} bones are NOT properly aligned on X-axis");
|
||||
}
|
||||
}
|
||||
|
||||
// 완벽한 T포즈 적용
|
||||
private void ApplyPerfectTPose()
|
||||
{
|
||||
if (selectedAnimator == null)
|
||||
{
|
||||
Debug.LogError("No valid Humanoid Animator selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("=== Applying Perfect T-Pose ===");
|
||||
|
||||
// Undo 시스템에 등록
|
||||
Undo.RecordObject(selectedAnimator.gameObject, "Apply T-Pose");
|
||||
|
||||
// 단계 1: 팔 부분 조정
|
||||
AdjustArmBones();
|
||||
|
||||
// 단계 2: 다리 부분 조정
|
||||
AdjustLegBones();
|
||||
|
||||
Debug.Log("Perfect T-Pose applied successfully!");
|
||||
}
|
||||
|
||||
// 팔 뼈대 조정 (단계 1)
|
||||
private void AdjustArmBones()
|
||||
{
|
||||
Debug.Log("Adjusting arm bones...");
|
||||
|
||||
// 왼쪽 팔
|
||||
AdjustSingleArm(HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, "Left");
|
||||
|
||||
// 오른쪽 팔
|
||||
AdjustSingleArm(HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, "Right");
|
||||
}
|
||||
|
||||
// 다리 뼈대 조정 (단계 2)
|
||||
private void AdjustLegBones()
|
||||
{
|
||||
Debug.Log("Adjusting leg bones...");
|
||||
|
||||
// 왼쪽 다리
|
||||
AdjustSingleLeg(HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot, "Left");
|
||||
|
||||
// 오른쪽 다리
|
||||
AdjustSingleLeg(HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot, "Right");
|
||||
}
|
||||
|
||||
private void AdjustSingleLeg(HumanBodyBones lowerLeg, HumanBodyBones foot, string side)
|
||||
{
|
||||
Debug.Log($"Adjusting {side} leg...");
|
||||
|
||||
// LowerLeg (무릎) 조정
|
||||
Transform lowerLegBone = selectedAnimator.GetBoneTransform(lowerLeg);
|
||||
if (lowerLegBone != null)
|
||||
{
|
||||
// 로테이션은 건드리지 않음 (기존 회전값 유지)
|
||||
|
||||
// 로컬 X, Z 포지션만 0으로 변경
|
||||
Vector3 localPos = lowerLegBone.localPosition;
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
lowerLegBone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} LowerLeg - Local Rotation: {lowerLegBone.localRotation.eulerAngles}, Local Position: {lowerLegBone.localPosition}");
|
||||
}
|
||||
|
||||
// Foot (발목) 조정
|
||||
Transform footBone = selectedAnimator.GetBoneTransform(foot);
|
||||
if (footBone != null)
|
||||
{
|
||||
// 로테이션은 건드리지 않음 (기존 회전값 유지)
|
||||
|
||||
// 로컬 X, Z 포지션만 0으로 변경
|
||||
Vector3 localPos = footBone.localPosition;
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
footBone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} Foot - Local Rotation: {footBone.localRotation.eulerAngles}, Local Position: {footBone.localPosition}");
|
||||
}
|
||||
|
||||
// 발가락 조정
|
||||
AdjustToes(side);
|
||||
}
|
||||
|
||||
private void AdjustToes(string side)
|
||||
{
|
||||
Debug.Log($"Adjusting {side} toes...");
|
||||
|
||||
HumanBodyBones toeBone;
|
||||
|
||||
if (side == "Left")
|
||||
{
|
||||
toeBone = HumanBodyBones.LeftToes;
|
||||
}
|
||||
else // Right
|
||||
{
|
||||
toeBone = HumanBodyBones.RightToes;
|
||||
}
|
||||
|
||||
Transform bone = selectedAnimator.GetBoneTransform(toeBone);
|
||||
if (bone != null)
|
||||
{
|
||||
// 로테이션은 건드리지 않음 (기존 회전값 유지)
|
||||
|
||||
// 로컬 X, Z 포지션만 0으로 변경
|
||||
Vector3 localPos = bone.localPosition;
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
bone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} Toes - Local Rotation: {bone.localRotation.eulerAngles}, Local Position: {bone.localPosition}");
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustSingleArm(HumanBodyBones upperArm, HumanBodyBones lowerArm, HumanBodyBones hand, string side)
|
||||
{
|
||||
Debug.Log($"Adjusting {side} arm...");
|
||||
|
||||
// UpperArm 조정
|
||||
Transform upperArmBone = selectedAnimator.GetBoneTransform(upperArm);
|
||||
if (upperArmBone != null)
|
||||
{
|
||||
// 로컬 Rotation을 0,0,0으로 초기화
|
||||
upperArmBone.localRotation = Quaternion.identity;
|
||||
|
||||
// 로컬 X, Z 포지션을 0으로 변경
|
||||
Vector3 localPos = upperArmBone.localPosition;
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
upperArmBone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} UpperArm - Local Rotation: {upperArmBone.localRotation.eulerAngles}, Local Position: {upperArmBone.localPosition}");
|
||||
}
|
||||
|
||||
// LowerArm 조정
|
||||
Transform lowerArmBone = selectedAnimator.GetBoneTransform(lowerArm);
|
||||
if (lowerArmBone != null)
|
||||
{
|
||||
// 로컬 Rotation을 0,0,0으로 초기화
|
||||
lowerArmBone.localRotation = Quaternion.identity;
|
||||
|
||||
// 로컬 X, Z 포지션을 0으로 변경
|
||||
Vector3 localPos = lowerArmBone.localPosition;
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
lowerArmBone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} LowerArm - Local Rotation: {lowerArmBone.localRotation.eulerAngles}, Local Position: {lowerArmBone.localPosition}");
|
||||
}
|
||||
|
||||
// Hand 조정
|
||||
Transform handBone = selectedAnimator.GetBoneTransform(hand);
|
||||
if (handBone != null)
|
||||
{
|
||||
// 로컬 Rotation을 0,0,0으로 초기화
|
||||
handBone.localRotation = Quaternion.identity;
|
||||
|
||||
// 로컬 X, Z 포지션을 0으로 변경
|
||||
Vector3 localPos = handBone.localPosition;
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
handBone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} Hand - Local Rotation: {handBone.localRotation.eulerAngles}, Local Position: {handBone.localPosition}");
|
||||
}
|
||||
|
||||
// 손가락 조정 (엄지손가락 제외)
|
||||
AdjustFingers(side);
|
||||
}
|
||||
|
||||
private void AdjustFingers(string side)
|
||||
{
|
||||
Debug.Log($"Adjusting {side} fingers (excluding thumb)...");
|
||||
|
||||
// 엄지손가락을 제외한 손가락들
|
||||
HumanBodyBones[] fingerBones;
|
||||
|
||||
if (side == "Left")
|
||||
{
|
||||
fingerBones = new HumanBodyBones[]
|
||||
{
|
||||
HumanBodyBones.LeftIndexProximal,
|
||||
HumanBodyBones.LeftIndexIntermediate,
|
||||
HumanBodyBones.LeftIndexDistal,
|
||||
HumanBodyBones.LeftMiddleProximal,
|
||||
HumanBodyBones.LeftMiddleIntermediate,
|
||||
HumanBodyBones.LeftMiddleDistal,
|
||||
HumanBodyBones.LeftRingProximal,
|
||||
HumanBodyBones.LeftRingIntermediate,
|
||||
HumanBodyBones.LeftRingDistal,
|
||||
HumanBodyBones.LeftLittleProximal,
|
||||
HumanBodyBones.LeftLittleIntermediate,
|
||||
HumanBodyBones.LeftLittleDistal
|
||||
};
|
||||
}
|
||||
else // Right
|
||||
{
|
||||
fingerBones = new HumanBodyBones[]
|
||||
{
|
||||
HumanBodyBones.RightIndexProximal,
|
||||
HumanBodyBones.RightIndexIntermediate,
|
||||
HumanBodyBones.RightIndexDistal,
|
||||
HumanBodyBones.RightMiddleProximal,
|
||||
HumanBodyBones.RightMiddleIntermediate,
|
||||
HumanBodyBones.RightMiddleDistal,
|
||||
HumanBodyBones.RightRingProximal,
|
||||
HumanBodyBones.RightRingIntermediate,
|
||||
HumanBodyBones.RightRingDistal,
|
||||
HumanBodyBones.RightLittleProximal,
|
||||
HumanBodyBones.RightLittleIntermediate,
|
||||
HumanBodyBones.RightLittleDistal
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var fingerBone in fingerBones)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(fingerBone);
|
||||
if (bone != null)
|
||||
{
|
||||
// 로컬 Rotation을 0,0,0으로 초기화
|
||||
bone.localRotation = Quaternion.identity;
|
||||
|
||||
// 손가락 첫 마디(Proximal)는 X축을 유지, 나머지는 X, Z 포지션을 0으로 변경
|
||||
Vector3 localPos = bone.localPosition;
|
||||
if (fingerBone.ToString().Contains("Proximal"))
|
||||
{
|
||||
// 첫 마디는 X축 유지, Z축만 0으로
|
||||
localPos.z = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 두번째, 세번째 마디는 X, Z 모두 0으로
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
}
|
||||
bone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} {fingerBone} - Local Rotation: {bone.localRotation.eulerAngles}, Local Position: {bone.localPosition}");
|
||||
}
|
||||
}
|
||||
|
||||
// 엄지손가락 두번째와 세번째 마디 조정
|
||||
AdjustThumbFingers(side);
|
||||
}
|
||||
|
||||
private void AdjustThumbFingers(string side)
|
||||
{
|
||||
Debug.Log($"Adjusting {side} thumb intermediate and distal...");
|
||||
|
||||
HumanBodyBones[] thumbBones;
|
||||
|
||||
if (side == "Left")
|
||||
{
|
||||
thumbBones = new HumanBodyBones[]
|
||||
{
|
||||
HumanBodyBones.LeftThumbIntermediate,
|
||||
HumanBodyBones.LeftThumbDistal
|
||||
};
|
||||
}
|
||||
else // Right
|
||||
{
|
||||
thumbBones = new HumanBodyBones[]
|
||||
{
|
||||
HumanBodyBones.RightThumbIntermediate,
|
||||
HumanBodyBones.RightThumbDistal
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var thumbBone in thumbBones)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(thumbBone);
|
||||
if (bone != null)
|
||||
{
|
||||
// 로컬 Rotation을 0,0,0으로 초기화
|
||||
bone.localRotation = Quaternion.identity;
|
||||
|
||||
// X, Z 포지션을 0으로 변경
|
||||
Vector3 localPos = bone.localPosition;
|
||||
localPos.x = 0f;
|
||||
localPos.z = 0f;
|
||||
bone.localPosition = localPos;
|
||||
|
||||
Debug.Log($"{side} {thumbBone} - Local Rotation: {bone.localRotation.eulerAngles}, Local Position: {bone.localPosition}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 뼈대들의 부모-자식 관계를 일시적으로 분리
|
||||
private Dictionary<Transform, Transform> DetachBonesFromHierarchy()
|
||||
{
|
||||
Debug.Log("Detaching bones from hierarchy...");
|
||||
|
||||
Dictionary<Transform, Transform> originalParents = new Dictionary<Transform, Transform>();
|
||||
|
||||
// 모든 Humanoid 뼈대의 부모-자식 관계를 저장하고 분리
|
||||
for (int i = 0; i < HumanTrait.BoneCount; i++)
|
||||
{
|
||||
HumanBodyBones bone = (HumanBodyBones)i;
|
||||
Transform boneTransform = selectedAnimator.GetBoneTransform(bone);
|
||||
|
||||
if (boneTransform != null)
|
||||
{
|
||||
// 원래 부모를 저장
|
||||
originalParents[boneTransform] = boneTransform.parent;
|
||||
|
||||
// 뼈대를 최상위 레벨로 이동 (계층구조에서 분리)
|
||||
boneTransform.SetParent(null, true);
|
||||
|
||||
Debug.Log($"Detached {bone} from parent: {originalParents[boneTransform]?.name ?? "None"}");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"Detached {originalParents.Count} bones from hierarchy");
|
||||
return originalParents;
|
||||
}
|
||||
|
||||
// 뼈대들을 원래 부모-자식 관계로 복원
|
||||
private void RestoreBoneHierarchy(Dictionary<Transform, Transform> originalParents)
|
||||
{
|
||||
Debug.Log("Restoring bone hierarchy...");
|
||||
|
||||
foreach (var kvp in originalParents)
|
||||
{
|
||||
Transform bone = kvp.Key;
|
||||
Transform originalParent = kvp.Value;
|
||||
|
||||
if (bone != null)
|
||||
{
|
||||
// 원래 부모로 복원
|
||||
bone.SetParent(originalParent, true);
|
||||
Debug.Log($"Restored {bone.name} to parent: {originalParent?.name ?? "None"}");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("Bone hierarchy restored");
|
||||
}
|
||||
|
||||
private void AlignBodyBones()
|
||||
{
|
||||
Debug.Log("Aligning body bones...");
|
||||
|
||||
HumanBodyBones[] bodyBones = {
|
||||
HumanBodyBones.Hips,
|
||||
HumanBodyBones.Spine,
|
||||
HumanBodyBones.Chest,
|
||||
HumanBodyBones.UpperChest,
|
||||
HumanBodyBones.Neck,
|
||||
HumanBodyBones.Head
|
||||
};
|
||||
|
||||
foreach (var boneType in bodyBones)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(boneType);
|
||||
if (bone != null)
|
||||
{
|
||||
// 현재 위치에서 X축만 0으로 조정
|
||||
Vector3 newPosition = bone.position;
|
||||
newPosition.x = 0f;
|
||||
bone.position = newPosition;
|
||||
|
||||
// 회전을 0으로 설정 (똑바로 서있음)
|
||||
bone.rotation = Quaternion.identity;
|
||||
|
||||
Debug.Log($"Aligned {boneType} to X=0, rotation=0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetArmsToTPose()
|
||||
{
|
||||
Debug.Log("Setting arms to T-pose...");
|
||||
|
||||
// 왼쪽 팔
|
||||
SetArmToTPose(HumanBodyBones.LeftShoulder, HumanBodyBones.LeftUpperArm,
|
||||
HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, true);
|
||||
|
||||
// 오른쪽 팔
|
||||
SetArmToTPose(HumanBodyBones.RightShoulder, HumanBodyBones.RightUpperArm,
|
||||
HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, false);
|
||||
}
|
||||
|
||||
private void SetArmToTPose(HumanBodyBones shoulder, HumanBodyBones upperArm,
|
||||
HumanBodyBones lowerArm, HumanBodyBones hand, bool isLeft)
|
||||
{
|
||||
string side = isLeft ? "Left" : "Right";
|
||||
|
||||
// 어깨 위치 및 회전 조정
|
||||
Transform shoulderBone = selectedAnimator.GetBoneTransform(shoulder);
|
||||
if (shoulderBone != null)
|
||||
{
|
||||
// 어깨를 몸통 중심에서 적절한 거리로 이동
|
||||
Vector3 shoulderPos = shoulderBone.position;
|
||||
float shoulderOffset = isLeft ? -0.3f : 0.3f;
|
||||
shoulderPos.x = shoulderOffset;
|
||||
shoulderBone.position = shoulderPos;
|
||||
|
||||
// 어깨를 Z축 기준으로 회전하여 팔이 수평이 되도록 함
|
||||
float shoulderZRotation = isLeft ? 90f : -90f;
|
||||
shoulderBone.rotation = Quaternion.Euler(0, 0, shoulderZRotation);
|
||||
|
||||
Debug.Log($"Positioned {side} shoulder at X={shoulderOffset}, Z rotation={shoulderZRotation}°");
|
||||
}
|
||||
|
||||
// 상완 위치 및 회전 조정
|
||||
Transform upperArmBone = selectedAnimator.GetBoneTransform(upperArm);
|
||||
if (upperArmBone != null)
|
||||
{
|
||||
// 상완을 어깨에서 수평으로 뻗도록 위치 조정
|
||||
Vector3 upperArmPos = upperArmBone.position;
|
||||
float armLength = Vector3.Distance(shoulderBone.position, upperArmBone.position);
|
||||
upperArmPos.x = isLeft ? -armLength : armLength;
|
||||
upperArmBone.position = upperArmPos;
|
||||
|
||||
// 상완을 완전히 펴기 위해 회전 조정
|
||||
upperArmBone.rotation = Quaternion.identity;
|
||||
|
||||
Debug.Log($"Positioned {side} upper arm at X={upperArmPos.x}, rotation=0°");
|
||||
}
|
||||
|
||||
// 하완 위치 및 회전 조정
|
||||
Transform lowerArmBone = selectedAnimator.GetBoneTransform(lowerArm);
|
||||
if (lowerArmBone != null)
|
||||
{
|
||||
// 하완을 상완에서 수평으로 뻗도록 위치 조정
|
||||
Vector3 lowerArmPos = lowerArmBone.position;
|
||||
float forearmLength = Vector3.Distance(upperArmBone.position, lowerArmBone.position);
|
||||
lowerArmPos.x = isLeft ? -(upperArmBone.position.x + forearmLength) : (upperArmBone.position.x + forearmLength);
|
||||
lowerArmBone.position = lowerArmPos;
|
||||
|
||||
// 하완을 완전히 펴기 위해 회전 조정
|
||||
lowerArmBone.rotation = Quaternion.identity;
|
||||
|
||||
Debug.Log($"Positioned {side} lower arm at X={lowerArmPos.x}, rotation=0°");
|
||||
}
|
||||
|
||||
// 손 위치 및 회전 조정
|
||||
Transform handBone = selectedAnimator.GetBoneTransform(hand);
|
||||
if (handBone != null)
|
||||
{
|
||||
// 손을 하완에서 수평으로 뻗도록 위치 조정
|
||||
Vector3 handPos = handBone.position;
|
||||
float handLength = Vector3.Distance(lowerArmBone.position, handBone.position);
|
||||
handPos.x = isLeft ? -(lowerArmBone.position.x + handLength) : (lowerArmBone.position.x + handLength);
|
||||
handBone.position = handPos;
|
||||
|
||||
// 손을 자연스럽게 펴기 위해 회전 조정
|
||||
handBone.rotation = Quaternion.identity;
|
||||
|
||||
Debug.Log($"Positioned {side} hand at X={handPos.x}, rotation=0°");
|
||||
}
|
||||
}
|
||||
|
||||
private void AlignLegBones()
|
||||
{
|
||||
Debug.Log("Aligning leg bones...");
|
||||
|
||||
HumanBodyBones[] leftLegBones = {
|
||||
HumanBodyBones.LeftUpperLeg,
|
||||
HumanBodyBones.LeftLowerLeg,
|
||||
HumanBodyBones.LeftFoot,
|
||||
HumanBodyBones.LeftToes
|
||||
};
|
||||
|
||||
HumanBodyBones[] rightLegBones = {
|
||||
HumanBodyBones.RightUpperLeg,
|
||||
HumanBodyBones.RightLowerLeg,
|
||||
HumanBodyBones.RightFoot,
|
||||
HumanBodyBones.RightToes
|
||||
};
|
||||
|
||||
AlignSideLegBones("Left", leftLegBones, -0.2f);
|
||||
AlignSideLegBones("Right", rightLegBones, 0.2f);
|
||||
}
|
||||
|
||||
private void AlignSideLegBones(string side, HumanBodyBones[] legBones, float targetX)
|
||||
{
|
||||
foreach (var boneType in legBones)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(boneType);
|
||||
if (bone != null)
|
||||
{
|
||||
// 위치를 목표 X축으로 조정
|
||||
Vector3 newPosition = bone.position;
|
||||
newPosition.x = targetX;
|
||||
bone.position = newPosition;
|
||||
|
||||
// 다리 뼈대들을 똑바로 세우기 위해 회전 조정
|
||||
bone.rotation = Quaternion.identity;
|
||||
|
||||
Debug.Log($"Aligned {boneType} to X={targetX:F3}, rotation=0°");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetFingersAndToesToTPose()
|
||||
{
|
||||
Debug.Log("Setting fingers and toes to T-pose...");
|
||||
|
||||
// 손가락 설정 (완전히 펴짐)
|
||||
SetFingersToTPose(true); // 왼쪽
|
||||
SetFingersToTPose(false); // 오른쪽
|
||||
|
||||
// 발가락 설정 (자연스러운 상태)
|
||||
SetToesToTPose(true); // 왼쪽
|
||||
SetToesToTPose(false); // 오른쪽
|
||||
}
|
||||
|
||||
private void SetFingersToTPose(bool isLeft)
|
||||
{
|
||||
string side = isLeft ? "Left" : "Right";
|
||||
|
||||
// 모든 손가락 관절을 0도로 설정
|
||||
for (int finger = 0; finger < 5; finger++)
|
||||
{
|
||||
for (int joint = 0; joint < 3; joint++)
|
||||
{
|
||||
HumanBodyBones fingerBone = GetFingerBone(isLeft, finger, joint);
|
||||
if (fingerBone != HumanBodyBones.LastBone)
|
||||
{
|
||||
Transform bone = selectedAnimator.GetBoneTransform(fingerBone);
|
||||
if (bone != null)
|
||||
{
|
||||
bone.localRotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"Set {side} fingers to straight position");
|
||||
}
|
||||
|
||||
private void SetToesToTPose(bool isLeft)
|
||||
{
|
||||
string side = isLeft ? "Left" : "Right";
|
||||
|
||||
// 발가락을 자연스러운 상태로 설정
|
||||
HumanBodyBones toeBone = isLeft ? HumanBodyBones.LeftToes : HumanBodyBones.RightToes;
|
||||
Transform bone = selectedAnimator.GetBoneTransform(toeBone);
|
||||
if (bone != null)
|
||||
{
|
||||
bone.localRotation = Quaternion.identity;
|
||||
Debug.Log($"Set {side} toes to natural position");
|
||||
}
|
||||
}
|
||||
|
||||
private HumanBodyBones GetFingerBone(bool isLeft, int finger, int joint)
|
||||
{
|
||||
if (finger == 0) // 엄지
|
||||
{
|
||||
if (isLeft)
|
||||
{
|
||||
switch (joint)
|
||||
{
|
||||
case 0: return HumanBodyBones.LeftThumbProximal;
|
||||
case 1: return HumanBodyBones.LeftThumbIntermediate;
|
||||
case 2: return HumanBodyBones.LeftThumbDistal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (joint)
|
||||
{
|
||||
case 0: return HumanBodyBones.RightThumbProximal;
|
||||
case 1: return HumanBodyBones.RightThumbIntermediate;
|
||||
case 2: return HumanBodyBones.RightThumbDistal;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // 나머지 손가락들
|
||||
{
|
||||
if (isLeft)
|
||||
{
|
||||
switch (finger)
|
||||
{
|
||||
case 1: return joint == 0 ? HumanBodyBones.LeftIndexProximal :
|
||||
joint == 1 ? HumanBodyBones.LeftIndexIntermediate :
|
||||
HumanBodyBones.LeftIndexDistal;
|
||||
case 2: return joint == 0 ? HumanBodyBones.LeftMiddleProximal :
|
||||
joint == 1 ? HumanBodyBones.LeftMiddleIntermediate :
|
||||
HumanBodyBones.LeftMiddleDistal;
|
||||
case 3: return joint == 0 ? HumanBodyBones.LeftRingProximal :
|
||||
joint == 1 ? HumanBodyBones.LeftRingIntermediate :
|
||||
HumanBodyBones.LeftRingDistal;
|
||||
case 4: return joint == 0 ? HumanBodyBones.LeftLittleProximal :
|
||||
joint == 1 ? HumanBodyBones.LeftLittleIntermediate :
|
||||
HumanBodyBones.LeftLittleDistal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (finger)
|
||||
{
|
||||
case 1: return joint == 0 ? HumanBodyBones.RightIndexProximal :
|
||||
joint == 1 ? HumanBodyBones.RightIndexIntermediate :
|
||||
HumanBodyBones.RightIndexDistal;
|
||||
case 2: return joint == 0 ? HumanBodyBones.RightMiddleProximal :
|
||||
joint == 1 ? HumanBodyBones.RightMiddleIntermediate :
|
||||
HumanBodyBones.RightMiddleDistal;
|
||||
case 3: return joint == 0 ? HumanBodyBones.RightRingProximal :
|
||||
joint == 1 ? HumanBodyBones.RightRingIntermediate :
|
||||
HumanBodyBones.RightRingDistal;
|
||||
case 4: return joint == 0 ? HumanBodyBones.RightLittleProximal :
|
||||
joint == 1 ? HumanBodyBones.RightLittleIntermediate :
|
||||
HumanBodyBones.RightLittleDistal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HumanBodyBones.LastBone; // 유효하지 않은 경우
|
||||
}
|
||||
|
||||
// 기본 포즈로 리셋
|
||||
private void ResetToDefaultPose()
|
||||
{
|
||||
if (selectedAnimator == null)
|
||||
{
|
||||
Debug.LogError("No valid Humanoid Animator selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("=== Resetting to Default Pose ===");
|
||||
|
||||
// Undo 시스템에 등록
|
||||
Undo.RecordObject(selectedAnimator.gameObject, "Reset to Default Pose");
|
||||
|
||||
// 모든 뼈대의 로컬 회전을 0으로 리셋
|
||||
for (int i = 0; i < HumanTrait.BoneCount; i++)
|
||||
{
|
||||
HumanBodyBones bone = (HumanBodyBones)i;
|
||||
Transform boneTransform = selectedAnimator.GetBoneTransform(bone);
|
||||
|
||||
if (boneTransform != null)
|
||||
{
|
||||
boneTransform.localRotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("Reset to default pose completed!");
|
||||
}
|
||||
|
||||
// 믹사모 네이밍 매핑 및 일괄 변경 함수 추가
|
||||
private void RenameToMixamo()
|
||||
{
|
||||
if (selectedAnimator == null)
|
||||
{
|
||||
Debug.LogError("No valid Humanoid Animator selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
// HumanBodyBones와 믹사모 네이밍 매핑
|
||||
var mixamoMap = new Dictionary<HumanBodyBones, string>
|
||||
{
|
||||
{ HumanBodyBones.Hips, "mixamorig:Hips" },
|
||||
{ HumanBodyBones.LeftUpperLeg, "mixamorig:LeftUpLeg" },
|
||||
{ HumanBodyBones.LeftLowerLeg, "mixamorig:LeftLeg" },
|
||||
{ HumanBodyBones.LeftFoot, "mixamorig:LeftFoot" },
|
||||
{ HumanBodyBones.LeftToes, "mixamorig:LeftToeBase" },
|
||||
{ HumanBodyBones.RightUpperLeg, "mixamorig:RightUpLeg" },
|
||||
{ HumanBodyBones.RightLowerLeg, "mixamorig:RightLeg" },
|
||||
{ HumanBodyBones.RightFoot, "mixamorig:RightFoot" },
|
||||
{ HumanBodyBones.RightToes, "mixamorig:RightToeBase" },
|
||||
{ HumanBodyBones.Spine, "mixamorig:Spine" },
|
||||
{ HumanBodyBones.Chest, "mixamorig:Spine1" },
|
||||
{ HumanBodyBones.UpperChest, "mixamorig:Spine2" }, // UpperChest는 있는 경우만
|
||||
{ HumanBodyBones.Neck, "mixamorig:Neck" },
|
||||
{ HumanBodyBones.Head, "mixamorig:Head" },
|
||||
{ HumanBodyBones.LeftShoulder, "mixamorig:LeftShoulder" },
|
||||
{ HumanBodyBones.LeftUpperArm, "mixamorig:LeftArm" },
|
||||
{ HumanBodyBones.LeftLowerArm, "mixamorig:LeftForeArm" },
|
||||
{ HumanBodyBones.LeftHand, "mixamorig:LeftHand" },
|
||||
{ HumanBodyBones.RightShoulder, "mixamorig:RightShoulder" },
|
||||
{ HumanBodyBones.RightUpperArm, "mixamorig:RightArm" },
|
||||
{ HumanBodyBones.RightLowerArm, "mixamorig:RightForeArm" },
|
||||
{ HumanBodyBones.RightHand, "mixamorig:RightHand" },
|
||||
// 왼손 손가락
|
||||
{ HumanBodyBones.LeftThumbProximal, "mixamorig:LeftHandThumb1" },
|
||||
{ HumanBodyBones.LeftThumbIntermediate, "mixamorig:LeftHandThumb2" },
|
||||
{ HumanBodyBones.LeftThumbDistal, "mixamorig:LeftHandThumb3" },
|
||||
// mixamo에는 Thumb4가 있으나, Unity에는 없음
|
||||
{ HumanBodyBones.LeftIndexProximal, "mixamorig:LeftHandIndex1" },
|
||||
{ HumanBodyBones.LeftIndexIntermediate, "mixamorig:LeftHandIndex2" },
|
||||
{ HumanBodyBones.LeftIndexDistal, "mixamorig:LeftHandIndex3" },
|
||||
{ HumanBodyBones.LeftMiddleProximal, "mixamorig:LeftHandMiddle1" },
|
||||
{ HumanBodyBones.LeftMiddleIntermediate, "mixamorig:LeftHandMiddle2" },
|
||||
{ HumanBodyBones.LeftMiddleDistal, "mixamorig:LeftHandMiddle3" },
|
||||
{ HumanBodyBones.LeftRingProximal, "mixamorig:LeftHandRing1" },
|
||||
{ HumanBodyBones.LeftRingIntermediate, "mixamorig:LeftHandRing2" },
|
||||
{ HumanBodyBones.LeftRingDistal, "mixamorig:LeftHandRing3" },
|
||||
{ HumanBodyBones.LeftLittleProximal, "mixamorig:LeftHandPinky1" },
|
||||
{ HumanBodyBones.LeftLittleIntermediate, "mixamorig:LeftHandPinky2" },
|
||||
{ HumanBodyBones.LeftLittleDistal, "mixamorig:LeftHandPinky3" },
|
||||
// 오른손 손가락
|
||||
{ HumanBodyBones.RightThumbProximal, "mixamorig:RightHandThumb1" },
|
||||
{ HumanBodyBones.RightThumbIntermediate, "mixamorig:RightHandThumb2" },
|
||||
{ HumanBodyBones.RightThumbDistal, "mixamorig:RightHandThumb3" },
|
||||
{ HumanBodyBones.RightIndexProximal, "mixamorig:RightHandIndex1" },
|
||||
{ HumanBodyBones.RightIndexIntermediate, "mixamorig:RightHandIndex2" },
|
||||
{ HumanBodyBones.RightIndexDistal, "mixamorig:RightHandIndex3" },
|
||||
{ HumanBodyBones.RightMiddleProximal, "mixamorig:RightHandMiddle1" },
|
||||
{ HumanBodyBones.RightMiddleIntermediate, "mixamorig:RightHandMiddle2" },
|
||||
{ HumanBodyBones.RightMiddleDistal, "mixamorig:RightHandMiddle3" },
|
||||
{ HumanBodyBones.RightRingProximal, "mixamorig:RightHandRing1" },
|
||||
{ HumanBodyBones.RightRingIntermediate, "mixamorig:RightHandRing2" },
|
||||
{ HumanBodyBones.RightRingDistal, "mixamorig:RightHandRing3" },
|
||||
{ HumanBodyBones.RightLittleProximal, "mixamorig:RightHandPinky1" },
|
||||
{ HumanBodyBones.RightLittleIntermediate, "mixamorig:RightHandPinky2" },
|
||||
{ HumanBodyBones.RightLittleDistal, "mixamorig:RightHandPinky3" },
|
||||
};
|
||||
|
||||
// UpperChest가 없는 경우 무시
|
||||
foreach (var kvp in mixamoMap)
|
||||
{
|
||||
if (kvp.Key == HumanBodyBones.UpperChest)
|
||||
{
|
||||
var upperChest = selectedAnimator.GetBoneTransform(HumanBodyBones.UpperChest);
|
||||
if (upperChest == null) continue;
|
||||
upperChest.name = kvp.Value;
|
||||
Debug.Log($"UpperChest 본이 있어 이름을 {kvp.Value}로 변경");
|
||||
continue;
|
||||
}
|
||||
var bone = selectedAnimator.GetBoneTransform(kvp.Key);
|
||||
if (bone != null)
|
||||
{
|
||||
bone.name = kvp.Value;
|
||||
Debug.Log($"{kvp.Key} 이름을 {kvp.Value}로 변경");
|
||||
}
|
||||
}
|
||||
Debug.Log("믹사모 네이밍으로 일괄 변경 완료!");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user