1. IK
IK처리를 하지 않고 Character의 움직임을 구현했다면 다음과 같이 경사로에 위치했을 때 발이 뜨는 현상을 볼 수 있다
자연스럽게 보이려먼 Character기준 왼쪽 다리는 구부리고 오른쪽 다리는 밑으로 더 내려와야 한다
로봇으로 비유를 하면 로봇 다리의 끝을 제어하고 싶다면 다리와 관련되어 있는 관절 부품 시작부터 다리의 끝 관절까지 제어해야 한다 이를 게임개발에서 IK를 사용하여 처리한다
IK는 말그대로 Inverse Kinematics이다 위 사진을 예시로 설명하면 왼쪽 경사면에 맞게 왼발을 배치하면 왼발에 연관되어 있는 상위 Bone (L_Knee, Pelvis) 이 어디 위치에 들어가야 하는지 역으로 계산할 수 있다는 것이다
IK 계산 방식은 다음과 같다
오른쪽 발에 가상의 Sphere가 있다 생각하고 지면까지 Sphere를 계속 생성하여 얼마나 내려야 하는지를 계산한다 (Sphere Trace)
이때 초록색 구체는 Sphere Trace로 바닥면과 충돌된 Sphere이다
이제 더 낮은 위치의 Hit Sphere를 찾고 발에서 해당 Hit Sphere 사이의 거리만큼 Pelvis (골반)을 아래로 움직일 수 있는지 계산한다
(Pelvis Bone은 다른 Bone들의 RootBone이다 -> Pelvis를 내리면 모든 Bone이 다 내려감)
Pelvis를 내릴 수 있다면 내리고 그 내린만큼 경사면에 있는 다리 Bone을 올려야 한다 이때 역 운동학(IK)을 이용하여 다리에 관련된 Bone들을 자연스럽게 굽히게 해주어야 한다
Bone들을 한번에 굽히는게 아니고 자연스럽게 굽히기 위해서 목표 수치까지 보간처리 (Interpolate)를 해야한다
결론적으로 제일 하단에 있는 발목 Bone을 위쪽의 빨간 구체까지 옮기려면 다른 무릎과 고관절 Bone들은 어떻게 배치를 해야하는지가 중요하다 다행히도 이러한 방정식은 UE에서 IK로 제공한다
IK를 적용하기 위해서는 Control Rig uasset을 만들어야 한다
사용하고 있는 Character의 Skeleton을 열어보면 IK를 적용할 수 있는 Bone들이 따로 준비가 되어 있다
ik_Bone들이 바로 IK를 적용할 수 있는 Bone이다 이 Bone들은 Mesh가 입혀져 있지 않다
만약 Character가 이러한 IK Bone이 없는 Skeleton을 사용하고 있다면 Virtual Bone을 추가하여 사용할 수 있다
이렇게 Root Virtual Bone이 생성된 걸 확인할 수 있다
만든 Root Virtual Bone에 IK를 적용시킬 다른 Bone들도 Virtual Bone으로 추가해주면 된다 ex) Foot_R, Foot_L
IK Bone을 사용하는 이유는 움직여도 Mesh가 없기 때문에 모양이 변하지 않기 때문이고 실제 Bone은 역운동학 계산을 해서 움직여야 하기 때문이다 -> IK Bone을 움직이고 나중에 실질적인 Bone을 움직인다
다시 Control Rig으로 돌아와 Rig Hierarchy에서 원하는 SkeletalMesh를 지정해준다
지정을 하면 뷰포트에 해당 Skeletal Mesh와 Rig Hierarchy에 Skeletal Tree가 출력된다
이제 Sphere Trace를 이용하여 IK를 적용해야 한다
대략 발목에서 바닥면까지로 Sphere Trace를 발사하면 된다
Control Rig도 다른 BP와 마찬가지로 변수, 함수 생성이 가능하고 Event Graph와 비슷한 기능을 하는 Rig Graph가 존재한다
SphereTrace를 해서 계산하는 함수를 만들어보자
다음과 같이 매개변수로 Rig Element Key타입을 사용하는 함수를 만들어준다
Rig Element Key는 Struct로 Type (Enum), Name (FName)으로 구성되어 있다
그리고 원하는 Bone의 Transform을 가져와야 한다
Get Transform-Bone : 원하는 Bone의 Transform을 FTransform으로 반환한다
원하는 Bone Item (FRigElementKey)를 인자로 가진다
이 Transform을 가지고 아래 방향으로 Sphere Trace를 발사해야 한다 이때 발과 부딪히지 않도록 Y축으로 조금 이동시킨 위치에서 발사하는게 좋다
Sphere Trace By Trace Channel : 시작위치에서 끝 위치까지 Sphere를 발사하여 충돌한 Object의 TraceChannel이 지정한 Channel과 일치하면 Hit처리를 한다 이때 Hit 결과는 bool, 맞은 위치는 FVector, 부딪힌 Normal 방향은 FVector로 반환한다
시작 위치 (FVector), 끝 위치 (FVector), Trace Chanel (Enum), Sphere Radius (float)을 인자로 가진다
적당한 Start Vector -> End Vector까지 Sphere Trace를 발사한 코드이다
이제 Hit Location을 return해준다
간단한 bool변수 (점프중이 아닐 때)를 만들고 해당 변수가 T일때만 위에 만든 Trace용 함수를 호출해주어야 한다
(Branch는 If문과 같다)
만든 함수의 인자로 Type과 원하는 Bone Name을 넣고 Sphere Trace에 Hit 된 위치 Vector의 Z값을 캐시한다
(Should Do IK Trace가 false면 value를 0으로 set)
BP에서 노드가 너무 길어지면 보기 힘들다 이때 사용하는것이 바로 Sequence이다
AddPin으로 실행 flow를 추가할 수 있다
Hit Location.Z값 까지 Interpolate 처리를 해주어야 한다 (보간)
Alpha Interpolate : Input Value까지 원하는 속도로 보간하여 값을 float로 반환한다
Input Value (float), 증가, 감소 속도(Interp Speed Increasing, Decreasing) (float), Inerp된 결과를 받을것인지? (bool)을 인자로 가진다 그 외에 인자는 우선 Defualt로 사용한다
이제 위에서 설명했듯 지면까지 더 짧은 거리가 어떤 것인지 알아야 한다 (그 거리만큼 다른 bone들을 움직여야 하기 때문)
Left Foot, Right Foot에서 발사한 Sphere Trace중 더 낮은 지면에 부딪힌 float값을 Pelvis Offset 변수에 Set해준다 (이만큼 Pelvis를 움직여야 함)
실질적으로 IK Bone을 움직여보자
Modify Transforms : 원하는 Bone을 원하는 Transform과 Weight를 적용하여 제어할 수 있다
실질적으로 움직여야 할 L,R Foot Z값만큼 Translation.Z에 넣어준다 단 이때 Pelvis는 Pelvis Z값 (Foot L, R Offset중 더 작은 값) 만큼 실제 Pelvis Bone을 제어해주어야 한다
Control Rig의 Forwards Solve Event는 AnimBP와 마찬가지로 실행하지 않아도 매 tick마다 돌아간다 따라서 수정결과를 좌측 뷰포트에서 실시간으로 확인이 가능하다
마무리로 IK를 적용해야 한다
UE5에는 Full Body IK 기능을 제공한다
Root에 RootBone을 넣어주고 Effectors에 IK를 적용시킬 실제 Bone을 넣고 Transform을 연결해준다 이때 Transform은 IK_Bone의 Transform이 된다
이때 FullBody IK Settings에서 Root Behavior를 Pin to Input으로 설정해야 한다
만든 Control Rig은 AnimBP에 연결해서 적용해야 한다
Control Rig Node를 배치하고 Branch에 걸어놓은 bool 변수를 설정하고 Control Rig Class를 직접 만든 클래스로 지정해준다
Control Rig Node 시작점에 넣은 bool변수는 점프중이 아니고 서있을때만 FullBody IK를 계산하도록 하기 위해서 만들어 놓은 것이다 따라서 Is Falling Not을 연결해준다
그리고 Speed가 0이 아닐때도 계산하면 걸어다닐때도 Foot IK가 적용된다 이를 방지하기 위해 Ground Speed가 0일때만 IK Pose가 적용되도록 Blend Poses by bool을 사용해야 한다
Blend Poses by bool : Active Value가 T이면 True Pose, F면 False Pose를 return한다 이때 Blend Time은 해당 Pose로 Blend되는데 필요한 시간을 의미한다
이렇게 IK가 잘 적용된 모습을 확인할 수 있다
'Unreal' 카테고리의 다른 글
20. Observer Pattern & Delegate (80) | 2024.02.07 |
---|---|
19. Collision & Overlap (1) (117) | 2024.01.31 |
17. Jump Animation (125) | 2024.01.24 |
16. Anim Instance (93) | 2024.01.23 |
15. Animation BP (89) | 2024.01.23 |