상체는 공격애니메이션이 가능한 블렌드스페이스 애니메이션
하체는 모션매칭의 움직임을 따라가도록 상하체를 분리해보도록 하겠습니다
검을 들었을때 사용할 상체 블렌드스페이스를 만들어줍니다
가로축값은 Direction 세로축값은 Speed를 축으로 제작했습니다
세로축값인 Speed는 캐릭터의 MaxWalkSpeed값을 가져왔고
가로축값인 Direction은 캐릭터의 캐릭터가 바라보는 전방 대비 실제 이동 방향을 가져왔습니다

Direction변수값을 계산하는 함수
void AMainCharacter::calculateDirection()
{
FVector velocity = GetVelocity();
velocity.Z = 0.f;
if (velocity.IsNearlyZero())
{
direction = 0.f;
return;
}
// 컨트롤러 Forward 기준
FRotator controlRot = GetControlRotation();
controlRot.Pitch = 0.f;
controlRot.Roll = 0.f;
FVector forward = FRotationMatrix(controlRot).GetUnitAxis(EAxis::X);
velocity.Normalize();
forward.Normalize();
float angle = FMath::Acos(FVector::DotProduct(forward, velocity));
angle = FMath::RadiansToDegrees(angle);
FVector cross = FVector::CrossProduct(forward, velocity);
if (cross.Z < 0)
{
angle *= -1.f;
}
direction = angle; // -180 ~ 180
}
컨트롤러에서 Tab을 누르면 변수값이 토글이되며 캐릭터의 함수를 호출하도록 하여
기존 모션에서 블렌드스페이스 상체 애니메이션이 변환되도록 제작하였습니다
컨트롤러에서 캐릭터가 Tab을 누르면 combatMode변수가 토글이되며 캐릭터의 HandlingWeaponDrawOrSheath()함수가 호출
void AMainCharacterController::InputKeyboardTabPressed()
{
APawn* myPawn = GetPawn();
if (myPawn)
{
AMainCharacter* mainCharacter = Cast<AMainCharacter>(myPawn);
if (mainCharacter)
{
mainCharacter->combatMode = !mainCharacter->combatMode;
mainCharacter->HandlingWeaponDrawOrSheath();
}
}
}
간단하게 애니메이션 몽타쥬만 실행시키는 함수입니다
void AMainCharacter::HandlingWeaponDrawOrSheath()
{
if (combatMode)
{
PlayAnimMontage(montageDrawWeapon);
}
else
{
PlayAnimMontage(montageSheathWeapon);
}
}
StateMachine안에는 아까 제작한 상체전용 블렌드스페이스가 들어있습니다

Layered Blend Per Bone 함수로 오른쪽 상체 애니메이션쪽만 적용되도록 하였습니다

clavicle_r Bone 기준으로 애니메이션을 나누고 토글변수인 CombatMode변수로 Blend Pose 를 결정하였습니다

사용할 Draw / Sheath 애니메이션을 리타게팅 후 리타게팅 애니메이션을 몽타쥬로 만들어준뒤
몽타주를 클릭뒤 슬롯 매니저를 선택해줍니다

DefaultGroup을 누른뒤 슬롯추가 를 누른뒤 rootSlot이라고 추가해줍니다

해당 애니메이션 몽타주를 슬롯 이름을 아까 만든 rootslot으로 변경해줍니다
애니메이션의 슬롯 이름을 변경하면 애니메이션이 T - Pose로 강제 변경되어버리는데
저장하고 다시 오픈하면 정상으로 돌아옵니다
사용할 애니메이션을 전부 슬롯이름을 rootslot으로 변경해줍니다

기본적으로 사용하고있는 애니메이션의 제일 뒷 노드에 New Save Cached Pose노드로 신호를 받아줍니다

Use cached pose 노드로 다시 신호를 받아온뒤 해당 그림처럼 노드를 정렬해줍니다

첫번째 Layered blend per bone노드는 spine_01기준 4 입니다
Blend Depth의 영향은 Bone Name의 본을 기준으로 가까울수록 크게 영향을 받습니다

두번째 Layered blend per bone 노드는 root기준 1 입니다

첫번쨰 DefaultSlot은 그대로 두번째 DefaultSlot은 이름을 rootSlot으로 변경해줍니다

결과물


clavicle_r 기준으로 상체 애니메이션이 별도로 적용되는것을 확인할수있습니다

---
만약 상하체 분리가 잘 안된다면 몽타쥬의 슬롯을 이름을 root에서 default로 변경해보세요
'Unreal 프로젝트 다이어리 > 두번째 프로젝트' 카테고리의 다른 글
| Unreal - 콤보 공격 (0) | 2025.08.22 |
|---|---|
| Unreal - 무기 Draw (0) | 2025.08.19 |
| Unreal - Foot IK (0) | 2025.08.17 |
| Unreal - 모션매칭(Motion Matching) - 스키마 데이터 관리하기 (점프,달리기) (0) | 2025.08.15 |
| Unreal - 모션매칭(Motion Matching) - 기본이동 구현하기 (0) | 2025.08.09 |