경사진 지형에 캐릭터를 둘 경우 위화감이 조성되는데 이를 해결하기 위한 방법.
Inverse Kinematics를 적용하기 위한 단계
1. Sphere trace를 통해 바닥에서부터 발바닥까지의 높이 확인
2. 어느 발이 낮은 위치의 발인지 확인(오른발이 낮은 위치의 발)
3. 발 높이에 맞춰 골반과 그외의 골격구조 변경
골반의 위치를 낮추고, 그에 맞춰 오른 다리의 골격 위치도 변경시킴.
Inverse Kinematics Blueprint
먼저 Control Rig라는 Blueprint class를 하나 생성한다.
IK_Foot관련 bone이 없다면 Virtual Bone을 root에 생성하고, VB root_root에 foot_l과 foot_r을 검색하여 추가한다.
생성한 Control Rig에서Import Hierarchy
를 클릭하고 사용할 Skeletal Mesh를 선택한다.1. Sphere trace를 이용한 높이확인
이를 처리하기 위한 함수를 먼저 만들어야 한다.
Line Trace를 수행할 FootTrace함수를 생성한다.
Entry노드를 클릭하고 우측의 Details 패널에서 input 매개변수를 추가한다.
GetTransform 노드를 IKFootBone과 연결시켜 위에서 생성한 IK_Foot Bone의 Transform 정보를 받아온다.
GetTransform은 Transform을 반환하는데, Sphere를 약간 이격시키지 않으면 FootBone에 충돌하여 위아래로 LineTrace를 하지 않는다고 한다. y축으로 Transform을 약간 변형시킨다.
이제 Sphere Trace를 하도록SphereTraceByTraceChannel
노드를 추가한다.
GetTransform 노드에서 z축 위로는 50만큼, 아래로는 100만큼 trace하도록 노드를 추가해준다(Add와 Subtract노를 추가하고 return값을 먼저 vector(Start, End)에 연결하면 자동으로 vector값을 return함).
마지막으로 FootTrace함수의 리턴값인 벡터타입의 HitPoint를 Return 노드에 추가해주고 SpehreTraceByTraceChannel의 HitLocation과 연결시켜준다.
필요할때만 SphereTrace를 하도록 EventGraph로 돌아가 bool타입 변수를 하나 추가해준다.
- branch를 통해 참일 경우(SphereTrace가 필요한 경우) 위에서 만들어둔 FootTrace함수가 실행되도록 한다. 이때 IKFootBone의 타입을 Bone으로, Name은 만들어둔 IK_Foot관련 bone으로 설정한다.
FootTrace는 HitPoint를 리턴하는데, 리턴값의 z값(높낮이에 대한 골격구조 변경이므로)를 따로 저장할 변수를 하나 만들어준다.
오른쪽 발도 똑같이 적용시켜주기 위해 노드를 추가해준다.
ZOffset_LTarget과 ZOffset_RTartget은 타겟(바닥과 같은 충돌지점)까지의 거리에 대한 변수이다.
- 거짓일 경우
ZOffset_LTarget과 ZOffset_RTarget의 리턴값이 0이 되도록 설정한다.
Sequence 노드를 이용해 깔끔하게 정리하고 Comment를 추가해준다.2. Interpolation(보간)
먼저 보간을 위한 변수를 생성한다.
ZOffset_LTarget과 ZOffset_RTarget에서 ZOffset_L과 ZOffset_R로 보간할 것이다.
ZOffset_L과 ZOffset_R은 실제 타켓(바닥과 같은 충돌지점)에 대한 변수이다.
보간을 하기 위해Alpha Interpolate
노드를 추가한다.
Alpha Interpolate
노드는 Interp Speed에 따라 시작지점과 끝지점 사이의 값을 부드럽게 변화시킨다.
보간이라고 하면 보통 두개의 값을 받아 그 사이를 보간하는 것으로 사용되는데 Alpha Interpolate의 경우 하나의 값을 받아 보간한다.
앞에서 만든 FootTrace함수가 발바닥인 0에서 sphereTrace의 z축까지의 거리를 나타내므로 이미 시작지점을 포함하고 있기 때문이라고 하는것 같다.원문
I punched in print functions here and there to see what is going on under the hat.
It turns out the answer was in the sphere tracing. It returns a delta value between the starting position and the end position, not pinpointing the exact location in the world map. Therefore the output will be rather something simple like 0, 0, 30, instead of 235,375,600.
I was confused too because it was the global value it returns after all, so I expected the return value would look something like the latter of the above.
Alpha Interpolate starts from 0 to the z foot offset so you only need to plug in the target value.이것 말고도 속도의 변화에 따라 위치를 예측해서 보간하기 때문에 값이 하나만 있어도 된다라는 글도 있는데 거리=속도로 바꿔서 해석하면 비슷한 느낌의 설명인 것 같다.
[[[(((나중에 추가로 알게 되면 정리)))]]]
Interp Result
는 Result를 통해 다음 단계에서의 입력으로 사용되도록 한다.
좌우 둘다 동일하게 노드를 추가하고 연결해줌으로써 ZOffset_L과 ZOffset_R에 보간된 결과를 할당한다.
마지막으로 노드들을 묶어 Comment를 추가해준다.3. 낮은 값 확인
골반을 움직이기 위핸 가장 낮은 값을 확인하는 단계이다.
ZOffset_Pelvis라는 변수를 하나 만든다.
가장 낮은 갚을 구하도록 노드를 구성해주고
결과값을 ZOffset_Pelvis에 저장한다.IK Bone 변형
Modify Transforms
노르를 생성하고, Type은 Bone, 대상 Name은 미리 생성해둔 ik_foot_l을 선택한다.
대상 지점까지 추적해서 변형시키므로, ZOffset_L노드를 Translation의 Z핀와 연결시킨다.
마지막으로 Mode를 Additive Global로 선택한다(Global 공간에서 작동하기 때문).
똑같은 단계를 ik_foot_r과 pelvis에도 적용시킨다.
전체 노드를 Sequence C에 연결시키고, comment를 달아준다.전체 Bone 변경
하체만 변형시키면 전체적인 밸런스가 맞지 않으므로
FullBodyIK
노드를 추가하여 전신의 모든 관절을 고려한 자연스러운 움직임을 만들어낸다.
먼저 Root bone이 Pelvis이므로 Pelvis로 변경한다.
Effectors는 적용시킬 bone을 지정할 수 있다.
foot_l을 고르고, ik_foot_l의 transform을 연결시켜 어떻게 변형시킬지 정한다.
Effectors 오른쪽의 +버튼을 누르면 노드를 추가하지 않고 똑같은 작업이 가능하다.
foot_r도 똑같이 적옹시켜주고 Comment를 달아준다.
마지막으로 Animation Blueprint에서 적용시키기만 하면 된다.
먼저Control Rig
노드를 추가해준다.
우측의 Details 패널에서 만든 Control Rig를 선택한다.
Animation Blueprint에서 변수를 사용하기 위해 눈표시를 켜준다(public으로 변경시켜줌).
다시 만들어둔 Control Rig 파일로 가서 우측의 Details 패널의 Output쪽을 보면 bool type 변수 사용이 가능하다.
추가로 Full Body IK 노드에서 Settings에 가면 Root Behavior이 있다. Pre Pull이 아닌 Pin to Input으로 변경시켜야 한다.
- Pre Pull
Stetched Effectors는 캐릭터의 손이나 발과 같은 움직이는 부분을 말하는것 같다.
이런 손과 발 등의 움직임에 대한 평균을 사용해서 Root bone과 그 하위 bone을 이동하고 회전시킬 수 있도록 하고, 멀리 있는(아마 수치적으로 계산하는데 걸린다는 의미인거 같음) 목표지점에 빠르게 도달하기 위한 수렴을 돕는다고 한다.
Pelvis를 lowest value를 통해 pelvis값을 얻어냈으므로 Pelvis를 input pose에 고정시킨 후 조정할 것이므로 사용하지 않은것 같음.- Pin to Input
Root bone의 이동 및 회전을 Input pose에 맞춰 lock시키고, Root bone에 적용된 모든 bone 설정을 무시한다. partial-body solves(부분적 몸체 문제라고 해석하기엔 이상해서 그냥 partial-body solves라고 함) 해결에 적합하다.
pelvis를 input pose에 고정시키고 나머지 부분을 설정하는 것이므로 pin to input을 선택함.- Free
Root bone을 다른 bone들과 동일하게 취급하며, 자유롭게 이동하거나 root에 적용된 모든 bone 설정에 따라 이동시킨다.
Pre Pull과 같이 ZOffset_Pelvis를 이용해 Pelvis를 미리 고정시켜두고 조정하므로 사용하지 않은것 같음.
(Pin to Input은 입력자세(ik_foot_l)로 변경시킨다 대충 그런 의미.)
떨어지지 않는 상태에서만 적용되야 하므로 IsFalling에 not boolean을 취하여 연결시켜준다.
Blend Poses by bool을 이용해 groundspeed가 0일 경우에만 적용되도록 한다.
실행시키면 오른발이 높이에 맞춰 올라가고, 그에 따라 전체적인 골격구조가 변경되는 것을 확인할 수 있다.