Version: 2020.2
언어: 한국어
타겟 매칭
루트 모션 - 작동 방식

역운동학(IK)

대부분의 애니메이션은 스켈레톤의 조인트 각도를 미리 정해진 값으로 회전하여 만듭니다. 자식 조인트의 포지션은 부모의 회전에 따라 변하므로 조인트 체인의 끝 점은 체인에 포함된 각 조인트의 각도와 상대 위치에 따라 결정될 수 있습니다. 이런 스켈레톤 포즈 메서드를 순운동학(FK)이라고 합니다.

하지만 조인트 포즈 작업을 반대 시각에서 바라보는 것이 유용한 경우도 많습니다. 공간에서 선택된 포지션에 따라서는 역으로 작업하여 적합한 조인트 방향을 찾아 해당 포지션에 조인트 끝점이 오도록 하는 방법이 유용할 수 있습니다. 이 방법은 사용자가 선택한 포인트의 오브젝트를 캐릭터가 건드리게 하거나, 울퉁불퉁한 표면 위에 캐릭터의 두 발이 자연스럽게 밀착해있도록 하려는 경우에 유용합니다. 이 접근법을 역운동학(IK)이라고 하며, _ 올바르게 설정된 아바타_가 있는 휴머노이드 캐릭터의 메카님에서 지원됩니다.

캐릭터에 IK를 설정하기 위해서는 일반적으로 캐릭터가 상호작용하는 씬 주위에 오브젝트에 배치하고, 그런 다음 스크립트를 통해 IK를 설정합니다. 특히 다음과 같은 애니메이터 함수를 사용합니다. SetIKPositionWeight, SetIKRotationWeight, SetIKPosition, SetIKRotation, SetLookAtPosition, bodyPosition, bodyRotation

위 예에서는 원통형 오브젝트를 쥐고 있는 캐릭터를 표시합니다. 이렇게 하려면 어떻게 해야 될까요?

우선 유효한 아바타가 있는 캐릭터부터 시작합니다.

다음, 캐릭터에 적용되는 최소한 한 개 니메이션이 있는 애니메이터 컨트롤러를 만듭니다. 그 후 애니메이터 창의 레이어 섹션에서 레이어의 톱니바퀴 모양의 설정 아이콘을 클릭하고, 이 때 나타나는 메뉴에서 IK 패스 체크박스를 선택합니다.

디폴트 레이어의 IK Pass 체크박스 설정
디폴트 레이어의 IK Pass 체크박스 설정

애니메이터 컨트롤러가 캐릭터의 Animator 컴포넌트에 할당되어 있는지 확인합니다.

다음, 실제로 IK를 처리할 스크립트에 연결합니다. 여기서는 IKControl 이라는 이름을 사용합니다. 이 스크립트는 캐릭터의 오른손에 대해 IK 타겟을 설정하고, 오른손이 바라보는 포지션이 오른손으로 쥐고 있는 오브젝트와 일치하도록 설정합니다.

using UnityEngine;
using System;
using System.Collections;

[RequireComponent(typeof(Animator))] 

public class IKControl : MonoBehaviour {
    
    protected Animator animator;
    
    public bool ikActive = false;
    public Transform rightHandObj = null;
    public Transform lookObj = null;

    void Start () 
    {
        animator = GetComponent<Animator>();
    }
    
    //a callback for calculating IK
    void OnAnimatorIK()
    {
        if(animator) {
            
            //if the IK is active, set the position and rotation directly to the goal. 
            if(ikActive) {

                // Set the look target position, if one has been assigned
                if(lookObj != null) {
                    animator.SetLookAtWeight(1);
                    animator.SetLookAtPosition(lookObj.position);
                }    

                // Set the right hand target position and rotation, if one has been assigned
                if(rightHandObj != null) {
                    animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
                    animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1);  
                    animator.SetIKPosition(AvatarIKGoal.RightHand,rightHandObj.position);
                    animator.SetIKRotation(AvatarIKGoal.RightHand,rightHandObj.rotation);
                }        
                
            }
            
            //if the IK is not active, set the position and rotation of the hand and head back to the original position
            else {          
                animator.SetIKPositionWeight(AvatarIKGoal.RightHand,0);
                animator.SetIKRotationWeight(AvatarIKGoal.RightHand,0); 
                animator.SetLookAtWeight(0);
            }
        }
    }    
}


캐릭터의 손이 오브젝트의 내부 중심(실린더의 피벗 포인트)까지 들어가도록 하려는 것은 아니므로, 빈 자식 오브젝트(여기서는 “실린더 그랩 핸들”)를 손이 실린더에 있어야 하는 포지션에 놓고 적절히 회전시킵니다. 그러면 이 자식 오브젝트가 손의 타겟이 됩니다.

빈 게임 오브젝트가 IK 타겟으로 동작하므로, 표시되는 실린더 오브젝트 위에 손이 올바르게 놓입니다.
빈 게임 오브젝트가 IK 타겟으로 동작하므로, 표시되는 실린더 오브젝트 위에 손이 올바르게 놓입니다.

그러면 “그랩 핸들” 게임 오브젝트가 IKControl 스크립트의 “오른손 오브젝트” 프로퍼티로 할당됩니다.

예제에서는 바라보는 타겟이 실린더 자체로 설정되었으므로 핸들이 실린더 바닥 가까이에 있어도 캐릭터가 오브젝트의 중심 방향을 곧장 바라보게 됩니다.

플레이 모드에 진입하면 IK가 작용하는 것을 실제로 볼 수 있습니다. IKActive 체크박스를 클릭하면서 캐릭터가 오브젝트를 잡았다 놓는 모습을 관찰하고 플레이 모드에서 실린더를 이리저리 움직여 보면서 팔과 손이 오브젝트를 따라가는 모습을 확인해야 합니다.

타겟 매칭
루트 모션 - 작동 방식