Foot Ik는 경사면에 따라서 발의 위치를 수정하여 자연스러운 모션이 될 수 있도록 하는 기법이다.
Foot Ik가 적용되지 않는 다면 케릭터는 허공에 붕뜬 상태로 서있게 된다.
그러나 Foot Ik가 적용되면 자연스럽게 비탈면에 맞춰 발을 이동시키고 서있을 수 있게된다.
Foot Ik의 Ik는 inverse kinematics로 역기구학이라는 뜻을 의미한다. 이는 Foot Ik가 발의 위치를 수정하고나면 발의 위치에 맞추어 모델의 전신을 수정하도록 하기 때문에 이렇게 불리는 것.
연산의 순서는 이렇다.
1. 먼저 발을 기준으로 바닥면의 위치를 검사한다
2. 바닥면의 위치로 발을 옮겨준다
3. 옮겨진 발에 맞추어 케릭터의 중심인 Pelvis도 옮겨준다
간단히 표현했는데 Foot Ik 연산을 하나씩 뜯어보며 설명하겠다.
위의 그림은 Control Rig에 생성한 연산식인데 Sequence노드 이전을 설명하고 위에서부터 차례대로 내려오도록 하겠다.
Control Rig을 통해서 Foot Ik를 적용하는 이유는 아래와 같다.
Control Rig에 대한 언리얼 공식문서의 설명이다.
언리얼 엔진은 캐릭터를 엔진 내에서 직접 리깅 및 애니메이팅할 수 있는 애니메이션 툴 세트인 컨트롤 릭을 제공합니다. 컨트롤 릭을 사용하면 외부 툴에서 리깅 및 애니메이팅할 필요 없이 언리얼 에디터에서 직접 이를 수행할 수 있습니다. 이 시스템을 사용하면 캐릭터의 커스텀 컨트롤을 생성 및 리깅하고, 시퀀서 에서 애니메이팅하고, 애니메이팅 프로세스를 보조하기 위한 다양한 애니메이션 툴을 이용할 수 있습니다.
간단히 말해서 Control Rig을 통해서 실시간으로 모델을 수정할 수 있다는 것. 즉, 애니메이션이 아니라 주위 환경에 맞추어 계산을 통해 모델의 수정이 필요한 부분에 대해서 Control Rig을 통해 적용을 할 수 있다는 것이다.
Foot Ik는 이런 용법에 딱 맞는 경우로 바닥의 환경에 따라서 개별 애니메이션으로는 적용할 수 없는 부분이지만 실시간 연산을 통해서 수정을 하는 것.
Control rig을 생성하면서 연산에 대해 설명하겠다.
Control rig을 생성하고 나면 어떤 모델에대한 Control rig을 수행할지 선택한다
1. Foot Ik 1번 노드
발을 이동시키기 위해서 발의 bone을 바로 사용하는 것이 아니라 발목에 있는 쓰이지 않는 bone을 이용하여 연산을 먼저 수행한다. 그러기 위해서 해당 bone들에 발의 bone의 Transform 데이터를 적용시켜준다. 각각의 bone들을 Ik_foot_r, Ik_foot_l 이라고 부르겠다.
2. Foot Ik 2번 노드
Ik_foot_r, Ik_foot_l 을 이용해서 발 주위의 충돌검사를 시행하여 발의 위치를 조정하기 위한 값을 탐색한다. 충돌 검사 후 충돌이 발생했는지 여부, 충돌의 위치의 값, 충돌지점의 Normal값을 변수에 담아서 저장해둔다. 발이 2개이므로 왼발의 데이터를 담을 변수와 오른발의 데이터를 변수를 각각 생성하여 저장해둔다.
FindHitPoint 함수는 커스텀 함수로 충돌검사를 진행하는 함수다. 아래는 FindHitPoint함수의 내부이다.
함수의 내용은 복잡하지 않다. 전달받은 bone의 위치를 기준으로 발에 Y값 +3을 해주는데 Offset값이라고 생각하면 된다. 이후에 발을 기준으로 Z - 50와 Z + 40의 값을 해주고 Sphere Trace by object types를 해준다. bone을 기준으로 Z값을 +와 -를 모두 진행하여 검사하는 것은 물체 위에 발을 올려둘 때도 있고 혹은 평평한 길에서 갑자기 만나는 움푹파인 부분에 발이 빠지는 경우 등을 모두 찾아서 발의 위치를 수정해주기 위해서다. 둘 모두 예시로서 비슷한 경우들이 많기때문에 발의 아래 위로 검사해서 충돌을 찾는 것이 정확한 위치를 찾는데 도움이 될 것이다. 충돌지점의 리턴값으로는 Z값만을 돌려주는데 이건 발을 위 혹은 아래로만 이동시키기 위한 연산식들이기 때문에 다른 방향으로의 이동을 고려하지 않기때문에 Z값을 사용하기 위해 Z값만 리턴하는 것
3. Foot Ik 3번 노드
앞부분의 노드들은 보간을 진행하고 보간한 값을 Offset변수에 추가한다.
그리고 왼발의 offset과 오른발의 offset을 비교하여 더 작은 offset을 Pelvis의 Offset값으로 저장한다.
더 작은 값을 찾아서 Pelvis의 Offset값으로 저장하는 이유는 더 큰 Offset값을 찾아서 Pelvis의 Offset으로 저장하고 적용하게 되면 아래 그림의 (a)처럼 되어버리기 때문이다. 모델링의 bone들은 엮여있고 특히 척추이자 중심에 해당하는 Pelvis가 움직이면 전체 모델링이 움직이게 되는데 높은 곳을 기준으로 맞추면 낮은 곳에 있던 발이 척추의 움직을 따라서 딸려올라가게 되고 이상한 형태로 서 있게 된다. 따라서 해당 문제를 피하기 위해서는 낮을 곳을 기준으로 Pelvis를 이동시켜야하고 또한 바닥 역시 아래쪽에 있기때문에 더 작은 값을 찾아서 Offset값을 삼는 것이다.
4. Foot Ik 4번 노드
이제 Left_foot, Right_foot, Pelvis에 적용할 Offset값들을 구했으니 각 bone에 해당 값들을 적용시키기 위해 Transform에 각 Offset들을 적용한다.
5. Foot Ik 5번 노드
여기까지 적용했다면 발이 충돌위치에 따라 아래 위로 이동하는 것은 끝난 것이다. 그러나 여기까지만 한다면 발이 바닥의 형태에 따라서 아래 그림과 같이 꺽이는 모양을 가지지 않는다.
이 문제를 해결하기 위해 아까 저장해 두었던 충돌지점의 Normal값을 사용한다.
발의 Transform에는 이미 offset이 적용되어 이동이 완료된 상태이기 때문에 이동에 대해서는 더이상 수정하지 않고 Aim math와 충돌지점의 normal값을 이용해서 Transform의 Rotation을 회전시킬 Rotation의 크기를 구하고 Transform의 Rotation과 Aim math에서 구한 Rotation값을 곱하여 Rotation값에 적용시키면 굽는 발을 구현할 수 있게된다.
최종적으로 Full body Ik를 사용하여 각 bone의 Transform 값들을 적용시키는데 이걸 사용하는 이유는 모든 bone이 엮여 있기때문에 자연스러운 움직임을 구현하기 위해서는 발이 이 움직임에 따라 다른 bone들 역시 움직여야 한다. pelvis의 경우 offset을 주어서 들어올렸지만 이것만으로는 자연스러운 움직임이 되지 않는다.
아래 그림을 다시 보면 (b)와 (c)의 차이는 케릭터의 골반이 (c)에서는 약간 회전해있다는 점이다. 이런 자연스러운 모델의 움직임을 구현하기 위해서는 Full body Ik를 사용하여 발의 bone들을 움직여주어야한다.
최종적으로는 ABP의 Output pose의 직전에 적용시켜 주면 된다.
위 그림에서는 애니메이션 블루프린트로 적용이 되었지만 프로젝트에따라 Foot Ik Control Rig으로 바로 적용시켜도 무방한 부분이다.
여기까지 하면 Foot Ik가 적용된 케릭터의 움직임을 확인 할 수 있게된다.
'Unreal Engine' 카테고리의 다른 글
Delegate(언리얼 엔진) (1) | 2023.10.04 |
---|---|
Unreal Reflection(언리얼 프로퍼티 시스템) (1) | 2023.10.01 |
Material Function(Outline Shader에 사용) (0) | 2023.09.30 |
Outline Shader - 2 (0) | 2023.09.29 |
Outline Shader - 1 (1) | 2023.09.29 |