관리 메뉴

기억을 위한 기록들

MarketPlace / BluePrints /ALS(Advanced Locomotion System) V4 - 02 본문

UnrealEngine/Foot-Place IK 관련

MarketPlace / BluePrints /ALS(Advanced Locomotion System) V4 - 02

에드윈H 2020. 7. 8. 12:46

지난 글에서는 Foot IK을 하기 위해 사용되는 함수들을 알아보았다.

 

이제 해당 함수에서 구해낸 값들로 어떤식으로 적용되는지 살펴보자.

 

 

 

우선 SetFootOffsets 함수에서 Foot Offset L Location 이라는 Vector값이 어디서 사용되나 보자.

 

 

해당 변수를 레퍼런스 검색을 해보니 애니메이션 그래프 쪽에서 호출되고 있다.

 

 

Apply Foot + Pelvis Offsets

다리와 골반의 Offsets값들을 적용하는 부분이다. 아래에 Pelvis Offset을 적용하는 그래프가 있고,

 

위의 그림에서 '본 트랜스폼(변경)'으로 Foot Offset L Rotation과 함께 호출 되고 있다.

 

 

해당 그래프의 디테일을 살펴보면,

 

노란색 화살표로 표시 되어 나오는게 수정 되고 있는 부분들이다.

 

위에서부터 하나씩 살펴보면, 

우선 수정되고 있는 본은 'VB ik_foot_l_Offset' 이라는 본이다. 

 

VB라는 수식어가 앞에 붙은 이유는 'Virtual Bone'이라는 뜻으로 공식문서에서 친절하게 설명해준다.(귀찮은 거 아님!..)

 

https://docs.unrealengine.com/ko/Engine/Animation/Persona/VirtualBones/index.html

 

가상 본

에디터 안에서 IK 또는 애님 컨스트레인트 조인트를 추가할 수 있도록 해주는 Virtual Bone, 가상 본에 대한 개요입니다.

docs.unrealengine.com

간단히 설명하자면, "에디터 안에서 조준이나 IK 에 대한 타깃 조인트 계층구조를 변경할 수 있게 해주어 반복처리 시간을 빠르게 하는 데 도움이 됩니다. 이 기능이 추가되기 전에는 에디터 외부 3D 모델링 프로그램에서 본을 추가한 뒤 모든 애니메이션을 다시 임포트하고서 새로 포함된 조인트에 맞춰 애니메이션 데이터를 수정해야 했었습니다." 라고 하며, 엔진 에디터 상에서 애니메이션에 도움이 되는 본들을 빠르고 간편하게 추가삭제 할 수 있게 해주는 좋은 기능이다.

 

이제 해당 본을 스켈레탈 메시에서 보면,

 

 

ik_foot_l 에서 타깃 본도 ik_foot_l로 되어 조그맣게 표시되어 있다.

 

예를 들어 타깃 본을 root로 해서 추가해주면, 

 

이런식으로 표현된다. 그리고 하다보니 알아 낸것은 중복추가가 안된다는 것이다. 이미 타깃 본으로 설정 된 가상본이 있으면, 추가가 되지 않는다.

 

 

우선 여기까지 알아낸 것은, SetFootOffsets 함수에서 얻어낸 Offset값으로 가상 본으로 추가 된 VB ik_foot_l_offset이라는 본에 대한 Foot Offset L Rotation / Foot Offset L Location값으로 트랜스폼을 변경해주고 있다.

 

그리고 해당 값들은

 

Translation Mode는 'Add to Existing'이며, Translation Space는 'WorldSpace'로 계산되고 있다.

 

이는 기존 값에 World Space로 Location/Rotation 값이 증가감소 되고 있다는 것이다.

 

그리고 해당 값들의 적용 Alpha값은 

애님 커브 값으로 적용 되며, 'Enable_FootIK_L' 값은 이전에 계산함수에서도 사용된 커브인데 해당 커브는,

 

점프/구르기 등에는 값이 0이되며, 일단 걷기 달리기 중엔 항상 1이다. 그러므로 해당 본 트랜스폼 변경도

IK가 적용 가능한 상황에서만 적용되고 있다.

 

여기까지하고 한번 정리하면, 가상 본을 추가 해준 뒤, 해당 가상본의 위치를 바꿔주고 있다.

 

하지만 확인해본 결과 가상 본만으로는 발의 위치가 변경 되지 않는 다는 것이다.

 

왜일까? 우선 침착하게 밑을 좀 더 살펴보자.

 

오른발도 마찬가지로 왼발과 적용 해준뒤, 

골반 Offset을 적용 해주는 '본 트랜스폼(변경)'이 있고, 

해당 값은 이전글에서 했던 함수 SetPelvisIKOffset 내부에서 구해주고 있다. (Pelvis Alpha 값도 마찬가지로 함수내부에서 구한다.)

이전 글에 있던 함수

해당 애니메이션 그래프에서는 가상본을 쓰지 않고 원래 있던 Pelvis 본에 적용 해주고 있다.

 

Pelvis 본의 위치 

 

 

여기서는 크게 설명해볼건 없고 다음으로 넘어간다.

 

다시 애니메이션 그래프로 돌아와 그 밑으로는 

 

 

'본 트랜스폼(변경)' 2개가 보이는데 각 각  이름에서 유추해보는 것은 가상본을 knee (무릎)에 추가 해주었다.

스켈레탈 메시로 가보면 

 

foot 쪽에서 추가하여 타깃 본을 Knee로 해주었다.

 

 

해당 가상 본의 Location 값은 20.0,30.0,0.0으로 지정 해주었다.. 이거의 적용 이유는 아마 이 사람들이 연구해내어 얻어낸 결과 값이라 생각한다. (이전 CPP IK 글과 마찬가지로) 

Add to Existing 해주며 Bone Space에 추가해주고 있다.

 

알파 값은 마찬가지로 Enable_FootIK_L 를 사용해준다. (일반 상태일때는 항상 적용 된다는 것)

 

마찬가지로 오른쪽도 해준다. 여기서 다른것은 Translation 값이 왼쪽과 다르게 음수라는점이다.

 

여기까지 이고 대망의 적용 부분이 나온다.

 

 

 

 

해당 그래프를 미리 한번 보며 "아... 가상본을 이렇게 쓰는구나 하고 배웠다" 한번 살펴보자

해당 그래프 디테일을 살펴보면, 

 

우선 하나씩 살펴보면

 

 

IKBone으로 가상본이 아닌 foot_l을 지정해주고 있다.

익숙한 본 

그리고 Max Stretch Scale의 기본값은 1.2이나 1.5로 수정해주었다. 해당 값은

최대로 늘려준 셈이다.  Stretch의 뜻은 '뻗다'라는 뜻으로, 한계치에서 벗어나 뻣을수 있는 정도를 늘려준 셈이다.

해당 변수도 체크해주었다. 그리고 밑을 보자

 

 

여기서 이제 위에서 두차례에서 걸쳐 추가해준 가상본 2개(발목/무릎)을 적용 시켜주고 있다.

 

Effector Target으로 VB_ik_foot_l_Offset,

 

Joint Target으로 VB_ik_knee_target을 정해주었다.

 

 

즉, 위에서 '본 트랜스폼(변경)'을 가상 본들의 위치,회전을 조정해주고

 

이 "2 본 IK"에서 조정되고 있는 기본 foot_l, foot_r본은 가상 본들의 transform 영향을 받고 있는 것이다.

 

VB_ik_foot_l_offset인것을 다른 본으로 바꾸면 
hand 본으로 바꾸니 손에 붙어 버렸다.

이 처럼 foot_l의 본은 VB_ik_foot_l_Offset의 본(Effector)에 위치하고 있는 것이다.

 

 

그리고 아까 위 무릎 가상본(VB_ik_knee_target)에서 변경해준 위치로 

 

 

 

Joint Target 위치가 된것이였다.

 

자자

간단하게 요약하면 이러하다.

 

1. 해당 본 적용에 필요한 부위에 맞는 오프셋 값을 구한다.

 

2. 가상 본을 추가(발,무릎)하여 해당 오프셋 값은 Effector (적용되는) 부분에 Offset값을 정해주고,

   Joint Target이 되는 관절(무릎/팔꿈치)의 적절한 값을 찾아 준 뒤, Add to Exsting 해주며, 필요한 기능에 따라 World Space, BoneSpace, ComponentSpace를 바꿔주면 된다.

 

3. 마지막으로 추가 된 가상 본들을 이용하여 Effector Location과 Joint Target으로 잡아준다.

 

 

 

새로운걸 발견해냈다. 지금까지 가상본도 그렇고 2 본 IK 등도 제대로 이해하지 못했었는데 이번 기회에 이해 하게 되었다.

 

아 그리고 빼먹은게 있다(보류)

 

 

 

 

 

깔끔하게 새로 만들어 보았다.

 

결국에는 OffsetValue를 구하여 적용 시켜주면 나머지는 이미 설정되어 있는 값들에 이해 자연스럽게 움직이게 되는 것이다.

 

OffsetValue에 값을 주었더니 팔이 굽혀졌다.

 

둘러보다가 '2 본 IK'의 Stretch Scale 관련하여 테스트 해보았다. 현재 Allow Stretch 체크 해준 상태이다.

 

X Offset을 100 주었더니 팔이 뜯어졌다. 여기서 아까 Stretch Scale의 영향을 비교 해볼수 있는게

현재 1.5로 올려 주었지만 비 활성화 상태로 하면, 

강제로 늘어나지 않는다.

 

이제 마무리를 하자면, 이전 유튜브 CPP 강의에서는  가상본을 사용하지 않으며,

 

Effector Location World Location으로 해주며, Joint Target값을 지정해주며 작동하게 되었고,

 

이번 IK는 Effector도 그렇고 Joint Target의 지정을 가상본을 이용했다.

 

두가지 방법 중에 프로젝트의 상황에 따라 다르게 적용하면 될듯하다.

 

이해를 돕게 이 프로젝트를 무료로 배포 해준 'LongmireLocomotion' 에게 감사인사를 전한다.