유니티 기본기 : 애니메이터(Animator) 3편

애니메이션 레이어(Animation Layer)

Karo
Supercent Blog 슈퍼센트 블로그
10 min readMar 27, 2024

--

애니메이터(Animator)란?

애니메이터(Animator)는 유니티에서 제공하는 애니메이션 시스템 중 하나인 메카님(Mecanim)이라고 불리는 시스템의 핵심 컴포넌트입니다.

2편에서는 애니메이터 컨트롤러를 편집하는 방법에 대해서 알아보았습니다. 이어서 3편에서는 애니메이터 컨트롤러에서 사용되는 애니메이션 레이어(Animation Layer)에 대해서 알아보도록 하겠습니다.

애니메이션 레이어(Animation Layer)란?

애니메이션 레이어(Animation Layer)는 캐릭터의 다양한 부분을 독립적으로 제어할 수 있게 해주는 기능입니다. 이를 활용해 캐릭터의 특정 부분만 애니메이션을 적용할 수 있습니다.

예를 들어, 캐릭터의 몸은 춤을 추면서 표정이 상황에 따라 다양한 표정 애니메이션을 실행하거나 하체는 달리고 있으면서 상체는 총을 쏘는 애니메이션을 실행할 수 있습니다.

애니메이터 뷰의 애니메이션 레이어 목록

애니메이션 레이어를 사용하는 방법은?

애니메이션 레이어(Animation Layer)는 애니메이터 뷰의 좌측 상단에 있는 탭을 클릭하여 확인할 수 있습니다. 애니메이터 컨트롤러(Animator Controller)를 생성하면 기본적으로 Base Layer를 가지고 있으며 “+버튼”을 통해 신규 레이어를 추가하거나 다음과 같은 방법으로 레이어의 순서를 변경할 수 있습니다.

애니메이션 레이어를 추가하거나 순서를 변경하는 예시

추가된 레이어는 기존의 Base Layer와 동일하게 상태(State)를 정의하고 전환(Transition)을 설정할 수 있으며 독립된 상태머신(State Machine)으로써 동작하게 됩니다. 이때, 파라미터(Paramaters)의 경우에는 모든 레이어에 동일하게 적용됩니다.

추가된 애니메이션 레이어에 상태 및 전환을 추가하고 공유된 파라미터를 사용하는 예시

애니메이션 레이어의 동작 방식은?

동작 방식을 편집하고자 하는 애니메이션 레이어의 우측 상단에 있는 “톱니바퀴 버튼”을 클릭해 해당 레이어가 어떤 방식으로 동작할 것인지를 편집할 수 있습니다.

애니메이션 레이어 설정 화면
  • Weight
    해당 레이어가 영향을 끼치는 가중치를 의미합니다. 해당 값이 0이면 0%, 1이면 100%를 의미합니다.
void AnimatorTest()
{
// 레이어의 순서는 위에서 부터 아래로 내려가며 0번 부터 시작합니다.
var baseLayerIndex = 0;
var currentWeight = anim.GetLayerWeight(baseLayerIndex);

// 해당 메서드를 통해 특정 레이어의 가중치를 조절할 수 있습니다.
anim.SetLayerWeight(baseLayerIndex, 1.0f);
}
  • Mask
    해당 레이어의 애니메이션들이 적용될 캐릭터의 부위를 의미합니다. 해당 설정을 통해서 상체 혹은 하체 등 특정 부위에만 애니메이션을 실행할 수 있습니다. 마스크가 설정되지 않은 경우에는 모든 부위에 애니메이션이 적용됩니다. 자세한 사항은 아래에서 추가로 다루도록 하겠습니다.
  • Blending
    해당 레이어가 적용되는 방식을 의미하며 두 가지 방식이 존재합니다.
    “Override”는 해당 레이어보다 하위의 레이어에서 적용되는 애니메이션을 완전히 대체합니다.
    “Additive” 는 해당 레이어보다 하위의 레이어에서 적용되는 애니메이션 위에 해당 레이어의 애니메이션을 추가합니다.
  • Sync
    특정 레이어와 완전히 동일한 상태 및 전환을 가지게 해주는 옵션입니다. 자세한 사항은 아래에서 추가로 다루도록 하겠습니다.
  • Timing
    Sync가 활성화되어 있을 때 선택할 수 있는 옵션으로 재정의된 애니메이션의 길이가 얼마간 재생될 것인지를 제어하는 옵션입니다. 자세한 사항은 아래에서 추가로 다루도록 하겠습니다.
  • IK Pass
    Animator의 IK 기능을 활용할 것인지를 결정하는 옵션입니다. IK에 대해서는 다음 편에서 다루도록 하겠습니다.

애니메이션 레이어(Animation Layer)에 대해 더 알고 싶다면 여기를 클릭해 주세요.

아바타 마스크(Avatar Mask)란?

캐릭터의 특정 부위에만 애니메이션을 적용하고자 할 때 사용하는 기능입니다. 해당 마스크를 통해 캐릭터의 몸 일부를 선택할 수 있으며 나머지 부분은 애니메이션에서 제외됩니다. 휴머노이드 및 제네릭 타입의 모델링 모두 사용할 수 있으며 타입에 따라 설정 방식이 서로 다릅니다.

아바타 마스크 편집 화면

다음과 같은 방법으로 아바타 마스크(Avatar Mask)를 생성할 수 있습니다.

아바타 마스크 생성 예시

휴머노이드에서 편집하는 방법

휴머노이드의 경우에는 상단의 인체 모형에서 원하는 부위를 토글해서 활성화/비활성화하는 것으로 마스킹 부위를 설정할 수 있습니다. 기본적으로는 모두 초록색으로 활성화되어 있으며 빈 영역을 클릭하는 것으로 일괄 활성화/비활성화가 가능합니다.

아바타 마스크 편집 예시 (Humanoid)

제네릭에서 편집하는 방법

제네릭의 경우에는 하단의 Transforms를 열어서 편집을 원하는 골격 구조를 불러와서 체크 박스를 통해 부위별 활성화/비활성화 여부를 설정할 수 있습니다. 기본적으로는 모두 체크되어있는 상태이며 하단의 버튼들을 통해 일괄 설정 및 일괄 해제 등의 편의 기능이 제공됩니다.

아바타 마스크 편집 예시(Generic)

아바타 마스크(Avatar Mask)에 대해 더 알고 싶다면 여기를 클릭해 주세요.

Sync옵션을 활용하는 방법은?

특정 레이어와 완전히 동일한 상태 및 전환을 가지게 해주는 옵션입니다. 해당 옵션을 활용해 대상 레이어의 애니메이션 클립만을 오버라이딩할 수 있습니다. 이때, Sync된 레이어와 대상 레이어의 상태(State) 혹은 전환(Transition)이 수정될 경우 두 레이어 모두 변경이 되므로 유의해 주세요. 오로지 애니메이션 클립만 재정의할 수 있습니다.

예를 들어 다음과 같은 경우에 활용할 수 있습니다.

  • 캐릭터가 걷거나 뛸 때 해당 상태별 표정 애니메이션을 설정하고 싶을 때
  • 캐릭터가 정상적인 상태일 때와 부상 중인 상태일 때의 각 애니메이션을 재정의하고 싶을 때
  • 캐릭터가 들고 있는 무기에 따라 상체 애니메이션을 재정의하고 싶을 때
Snyc 적용 예시

“Timing” 옵션의 경우 위에서 말했듯 재정의된 애니메이션의 길이가 얼마간 재생될 것 인지를 제어하는 옵션입니다. 해당 옵션의 활성화 여부와 관계없이 애니메이션의 재생 시간이 자동으로 조절되며 해당 옵션이 활성화된 상태라면 가중치를 기준으로 두 애니메이션 간의 균형을 맞추게 되며 비활성화한 경우에는 원본 레이어의 애니메이션을 우선시하게 됩니다.

Timing 옵션 사용 예시

예제

여태까지 애니메이션 레이어를 사용하기 위해 필요한 기본 사항을 모두 살펴보았습니다. 이제는 해당 기능을 활용해 다음과 같은 예제를 만들어 볼 것입니다.

  • 마우스 좌클릭 시 캐릭터가 움직입니다.
  • 마우스 우클릭 시 캐릭터가 상처 입습니다.
  • 캐릭터가 상처를 입었을 경우에는 움직이는 모션이 재정의됩니다.
public class SampleController : MonoBehaviour
{
const float CHANGE_STATE_TIME = 0.25f;
const int INJURED_LAYER_INDEX = 1;

static readonly int ANIM_MOVE = Animator.StringToHash("move");
static readonly int ANIM_HIT = Animator.StringToHash("hit");

[SerializeField] Animator _anim = null;

bool _isInjured = false;



void Update()
{
if (null == _anim)
return;

_anim.SetBool(ANIM_MOVE, Input.GetMouseButton(0));

if (_isInjured)
return;

if (!Input.GetMouseButtonDown(1))
return;

_isInjured = true;
_anim.SetTrigger(ANIM_HIT);
StartCoroutine(Co_ChangeToInjured());
}

IEnumerator Co_ChangeToInjured()
{
var elapsed = 0.0f;
while (elapsed < CHANGE_STATE_TIME)
{
yield return null;
elapsed += Time.deltaTime;

var weight = elapsed / CHANGE_STATE_TIME;
_anim.SetLayerWeight(INJURED_LAYER_INDEX, weight);
}

_anim.SetLayerWeight(INJURED_LAYER_INDEX, 1.0f);
}
}

끝맺음

지금까지 애니메이션 레이어(Animation Layer)가 무엇이며 어떤 식으로 활용할 수 있는지 알아보았습니다.

다음 편에서는 휴머노이드(Humanoid)IK(Inverse Kinematic)에 대해서 다룰 예정입니다.

이 글을 통해 애니메이터를 처음 접하신 분들도, 기존에 사용하고 계셨던 분들도 도움이 되었으면 좋겠습니다.

<유니티 기본기 시리즈 전체 보기>

더 많은 하이퍼 캐주얼 게임 개발 팁을 알고 싶으신가요?
지금 바로
여기를 클릭해서, 슈퍼센트의 파트너가 되어 보세요!

[Contact]
- E-mail: help@supercent.io
- Website:
corp.supercent.io

--

--