🎮Unreal4/C++_TPS

[UE4] Hand IK - FABRIK (Two Bone IK와 차이점, 몽타주 Curve)

공대 컴린이 2023. 3. 13. 20:53
728x90

🤲 Hand IK

블루프린트를 공부하면서 계단을 오를 때 자연스러운 Foot IK를 구현했었다. 

오늘은 총을 잡을 때 정확히 손이 총을 감싸쥘 수 있도록 Hand IK를 구현해보았다.

 

Player의 애니메이션 블루프린트에서 IK는 모든 애니메이션 연산이 끝나고 가장 마지막에 적용시켜야 하기 때문에 최종 애니메이션 포즈의 바로 전 단계에 위치시켰다.

IK를 구현하기 위한 Inverse Kinematics 레이어를 추가하였다.

 

먼저, IK를 사용하는 중인지를 애니메이션 블루프린트에 알려줄 bool 형 변수(bool UseIK)를 생성해주었다.

AnimInstance 클래스에서 bUseIK 변수를 선언한 뒤 블루프린트에서 사용할 수 있도록 BlueprintReadOnly, EditAnywhere 속성을 부여하였다.

 

bUseIK 변수는 Weapon의 IsUnarmed 모드가 False인 경우 True가 되도록 하였다.

 

이렇게 만들어진 Use IK 변수를 이용해 IK 적용 상태라면 FABRIK 가 적용될 수 있도록 구현하였다.

🤲 FABRIK (Forward And Backward Reaching Inverse Kinematics)

FABRIK는 중 R에 해당하는 Reaching은 말 그대로 "늘린다"는 뜻이다. FABRIK를 사용하면 Bone을 앞뒤로 늘려서 IK를 적용하는데, Foot IK를 구현할 때 사용한 Two Bone IK와는 차이가 있다. 

IK 자체의 원리(어느 Bone을 기준으로 어느 Bone까지 섞을것인가)는 모두 똑같지만 Two Bone IK특정 간격을 채우기 위해 늘려주었다면 FABR IK특정 위치에 붙이기 위해 늘려준다. 이밖에도 회전하는 각도를 제한하며 늘려주는 CCD IK가 있다.

 

IK는 Bone을 늘려야 함으로 프로그래밍에 의해 값이 바뀌어야 하기 때문에 컴포넌트 공간에서 이루어진다. 따라서 FABRIK를 bool 포즈 블렌딩과 캐시 포즈 사용 노드에 연결할 때 자동으로 컴포넌트 <-> 로컬 간의 공간 변환이 이루어진다.

 

Two Bone IK에서는 Effector"IK가 적용될 Bone"이었는데, FABRIK에서는 Effector가 다른 의미로 사용된다.

여기서 Effector는 End Effector라고 표기되며, "Effector가 끝날 지점"을 의미한다.

 

쉽게 말해 FABRIK에 대칭점을 설정한다고 생각하면 된다.

오른손을 대칭점으로 잡아 오른손의 대칭인 왼손이 오른손 위치까지 늘려지도록 할 수 있다. 이렇게 어느 지점까지 떨어뜨릴건지 왼손이 움직일 기준을 정하는것이 Effector이다.

예를들어 Effector에 0, 0, 0을 초기화한다면 왼손이 오른손에 붙어버릴 것이다.

 

나는 오른손으로 총을 꺼내들면 왼손이 총을 정확하게 받칠 수 있도록 왼손에 IK를 적용하였다.

Effector는 손의 Bone을 늘리므로 Bone Space로 설정하고, Rotation을 변경할 필요가 없으므로 No Change로 설정하였다.

Two Bone IK에서 조인트를 설정했던 것과 같이 Bone을 움직일 때 어디까지만 Bone을 변경시킬 것인지에 대한 기준으로 UpperArm_L (왼쪽 어깨)를 잡았다. 

Max Iterations는 IK를 계산할 때 Bone을 재귀연산하며 정밀도를 맞추는 데 사용되는 속성이다.

 

Effector의 Location 설정값으로 사용된 Left Hand Location 변수는 왼손이 정확히 총을 잡을 수 있도록 수치(FVector(-30, 15.5, 7))를 맞춰놓았다. 

 

그 결과 Hand IK가 성공적으로 적용되었다.

Hand IK 적용 전
Hand IK 적용 후


💡 몽타주 Curve

이때, 새로운 문제점이 발생하였는데 바로 Equip 동작을 수행할 때 왼손이 오른손에 붙어있는 것이었다.

이를 해결하기 위해 Equip 몽타주에 Curve를 생성하여 0일 때 IK가 적용되고, 1이면 IK가 적용되지 않도록 커브를 추가해주었다.

 

애니메이션 시작 시 커브 값을 1로 설정하여 IK가 적용되지 않도록 하고, Equip이 거의 끝나갈 때 커브 값을 0으로 설정하여 IK가 자연스럽게 적용되도록 하였다.

 

이렇게 만들어진 Curve값을 사용하기 위해 애니메이션 블루프린트에서 Get Curve Value 함수를 사용하였고, 0에서 1로 변환하며 음수가 나올 수 있지만 음수인지 양수인지는 상관없이 수치값만 사용하기 때문에 ABS를 취하였다.

 


참조

https://docs.unrealengine.com/4.27/ko/AnimatingObjects/SkeletalMeshAnimation/NodeReference/Fabrik/

 

FABRIK

Forward And Backward Reaching Inverse Kinematics, 앞뒤로 늘어나는 IK 를 사용하는 애니메이션 노드입니다.

docs.unrealengine.com

728x90