유니티(Unity)에서 애니메이션은 캐릭터, 객체, UI 요소 등의 움직임을 제어하고 시각적 효과를 추가하는 데 사용된다. 유니티는 기본적으로 애니메이터 컨트롤러(Animator Controller)와 애니메이션 클립(Animation Clip)이라는 두 가지 주요 요소를 통해 애니메이션 시스템을 관리한다. 애니메이터 컨트롤러는 각 애니메이션 클립 간의 전환을 설정하고, 복잡한 상태 전환 논리를 구성할 수 있도록 돕는다.
애니메이터 컨트롤러는 상태 머신(state machine) 기반으로 동작하며, 각 상태는 특정 애니메이션 클립을 나타낸다. 예를 들어, 게임 캐릭터라면 '대기', '걷기', '달리기', '점프' 등의 상태가 있을 수 있고, 각 상태에 해당하는 애니메이션 클립을 연결할 수 있다. 이를 통해 애니메이션 간의 전환을 부드럽게 하고, 사용자 정의 조건을 설정해 캐릭터의 동작 흐름을 제어할 수 있다. 상태 전환은 파라미터(parameter)를 통해 제어할 수 있으며, 이 파라미터는 변수 형태로 애니메이션 속도, 방향 등을 조정할 수 있게 해준다.
애니메이션 클립은 실제로 애니메이션 데이터를 저장한 파일로, 유니티 내에서 직접 생성하거나 외부 소프트웨어(Blender, Maya 등)에서 만들어 유니티에 가져올 수 있다. 각 클립에는 이동, 회전, 스케일, 색상 변화 등 다양한 트랜스폼(transform) 속성을 포함할 수 있다. 유니티의 애니메이션 창(Animation Window)에서 직접 편집할 수 있으며, 타임라인 형태로 각 프레임에서 객체의 속성을 조정하는 방식으로 구성된다. 또한 애니메이션 이벤트(Animation Event)를 삽입해 특정 타이밍에 원하는 동작을 추가할 수 있다.
1. 애니메이터(Animator)
유니티에서 오브젝트에 애니메이션을 추가하려면 먼저 Animator 컴포넌트를 오브젝트에 붙여주고, 해당 컴포넌트에 Animator Controller를 연결해야 한다. 이를 통해 유니티에서는 상황에 맞춰 오브젝트가 유동적으로 애니메이션을 실행하도록 설정할 수 있다.
Avatar는 오브젝트의 아바타 정보를 등록하는 속성이다. 휴머노이드 애니메이션을 사용하는 3D 오브젝트의 경우 뼈대(스켈레톤) 매핑 정보를 담고 있는 아바타를 등록해주어야 제대로 동작한다. 에셋을 사용하는 경우 보통 캐릭터의 아바타까지 포함하므로 해당 아바타를 등록해주면 된다. 아바타 속성은 3D 오브젝트의 애니메이션 제어에 필요한 정보를 담고 있다. 특히 휴머노이드 애니메이션을 사용하는 경우, 오브젝트의 뼈대 구조(스켈레톤)에 맞는 매핑 정보가 있어야 제대로 동작하기 때문에 이 속성에 맞는 아바타를 등록해주어야 한다.
Apply Root Motion은 애니메이터가 오브젝트의 트랜스폼 정보(위치와 회전)를 수정할 수 있도록 하는 설정이다. 이 옵션을 활성화하면 애니메이션에 따라 오브젝트가 앞으로 이동하거나 회전하는 등의 동작을 할 수 있다. 그러나 이 속성이 활성화된 상태에서 트랜스폼 정보를 제어하는 코드와 충돌할 경우, 예기치 않은 움직임이나 오류가 발생할 수 있으므로 주의가 필요하다.
Update Mode은 애니메이터의 업데이트 주기를 설정하는 옵션으로, 애니메이션의 시간 흐름과 물리적 상호작용에 영향을 준다. 세 가지 옵션 중 하나를 선택할 수 있다. Normal은 일반적인 Update() 주기에 맞춰 업데이트되며, Time.timeScale의 영향을 받아 애니메이션 속도가 변경된다. Animate Physics는 FixedUpdate() 주기에 맞춰 업데이트되어, Rigidbody를 이용해 물리 상호작용을 하는 오브젝트에 적합하며 마찬가지로 Time.timeScale의 영향을 받는다. Unscaled Time은 Update() 주기에 맞춰 업데이트되지만, Time.timeScale을 무시해 특수 효과로 타임스케일이 변경된 상황에서도 애니메이션이 정상 속도로 재생된다.
Culling Mode는 애니메이션의 컬링 기준을 설정하는 옵션으로 오브젝트가 카메라에 보이지 않을 때 애니메이션 처리 방식을 결정한다. Always Animate는 오브젝트가 카메라에 보이지 않아도 애니메이션을 계속 실행하며, 컬링 대상에서 제외된다. Cull Update Transforms는 오브젝트가 카메라에 보이지 않으면 리타겟팅, IK, 트랜스폼 업데이트만 비활성화하여 애니메이션은 계속 실행되지만 일부 정보만 컬링된다. Cull Completely는 오브젝트가 카메라에 보이지 않으면 애니메이션을 완전히 비활성화하고 컬링하여, 더 이상 리소스를 사용하지 않는다.
2. 애니메이션 설정
Animator 윈도우는 애니메이터 컨트롤러와 애니메이션 클립을 시각적으로 관리할 수 있는 도구이다. 애니메이터 컨트롤러와 애니메이션 클립은 프로젝트 창에서 우클릭 > Create > Animator Controller 또는 Animation을 선택하여 생성할 수 있으며 생성된 애니메이터 컨트롤러는 애니메이터에 등록된 후, 해당 오브젝트를 선택한 상태에서 애니메이터 창을 열면 기본적으로 Entry, Any State, Exit의 3가지 노드를 확인할 수 있다. 이 노드는 애니메이션의 흐름을 제어하는 역할을 하며, 애니메이션 상태 간의 전환을 관리하는 데 사용된다.
Entry 노드는 애니메이터에서 기본 상태를 정의하는 중요한 노드로, 오브젝트가 처음 활성화될 때 실행될 디폴트 애니메이션이 연결된다. 예를 들어, 플레이어 캐릭터의 애니메이션에서 기본적으로 'Idle' 애니메이션이 실행되도록 설정했다면, 애니메이터에 'Idle' 애니메이션 클립을 추가하고 이를 Entry 노드에 연결하면 된다. 만약 기본 애니메이션을 'Run'으로 바꾸고 싶다면, 해당 애니메이션을 우클릭 후 'Set Default Animation'을 선택해 Entry 노드와 연결된 애니메이션을 변경할 수 있다.
디폴트 애니메이션인 'Idle'에서 다른 애니메이션으로 전환하려면, Any State 노드를 활용할 수 있다. 예를 들어, 플레이어가 'Run' 버튼을 눌렀을 때 'Idle'에서 'Run' 애니메이션으로 전환하려면, Any State에서 'Run' 애니메이션을 실행하도록 조건을 설정한다. 이 조건은 일반적으로 'Run' 버튼을 누를 때 트리거되는 파라미터로 설정할 수 있다.
애니메이션이 실행되고 난 뒤 종료를 처리하려면 Exit 노드로 연결하면 된다. 예를 들어, 'Run' 애니메이션이 끝나면 'Exit' 노드를 통해 실행을 마친 후 다시 'Idle' 애니메이션으로 돌아오게 된다. 이 과정은 캐릭터가 달리기를 멈추고 원래 상태로 돌아오는 방식이다. Exit 노드를 설정하면, 애니메이션이 종료될 때 애니메이션의 흐름을 종료시키고, 설정된 디폴트 애니메이션으로 복귀한다.
Animation 등록하기
애니메이션은 프로젝트 창에서 우클릭 후 'Animation'을 선택하여 새로 생성할 수 있으며, 생성된 애니메이션은 애니메이터 창에 끌어다 놓아 새로운 애니메이션 노드를 만들 수 있다. 예를 들어, 캐릭터의 'Jump' 애니메이션을 만들고자 한다면, 프로젝트 창에서 'Animation'을 선택해 'Jump' 애니메이션을 생성한 뒤, 이를 애니메이터 창에 드래그하여 노드를 생성할 수 있다. 또 다른 방법으로는 애니메이터 창에서 우클릭 -> 'Create State' -> 'Empty'를 선택해 빈 노드를 만든 후, 'Motion' 영역에서 원하는 애니메이션을 선택해 등록할 수 있다. 에셋을 사용할 때는 에셋에 포함된 애니메이터를 그대로 활용할 수 있지만,
특정 애니메이션만 필요하다면 애니메이터를 새로 생성하고 필요한 애니메이션만 등록해 단순화할 수 있다. 예를 들어, 캐릭터가 'Idle', 'Run', 'Jump' 애니메이션만 필요하다면, 기존 애니메이터를 수정하기보다 새로운 애니메이터를 생성하여 이들만 등록하여 사용할 수 있다. 애니메이션을 편집하거나 동작을 확인하려면, 하이아라키 창에서 애니메이터가 포함된 오브젝트를 선택하고 'Animation' 윈도우를 통해 타임라인과 Property 설정 창을 확인하면서 애니메이션을 조정할 수 있다. 이를 통해 'Jump' 애니메이션이 정확히 어떻게 실행되는지 확인하고 필요한 수정 작업을 할 수 있다.
Add Property를 선택하면 애니메이션으로 조정할 수 있는 값을 선택할 수 있으며, 기본적으로 트랜스폼(위치, 회전, 크기) 정보를 포함하고, 해당 오브젝트의 컴포넌트나 하위 오브젝트의 컴포넌트도 선택 가능하다. 예를 들어, 캐릭터가 'Run' 애니메이션을 할 때, 캐릭터의 위치나 회전을 애니메이션으로 조정하고 싶다면, 'Add Property'를 통해 트랜스폼 컴포넌트를 추가할 수 있다. 이후 0초와 1초 지점에 기본 키프레임이 자동으로 추가되며, 이를 통해 애니메이션의 시작과 끝을 정의할 수 있다. 예를 들어, 0초에는 캐릭터의 위치가 (0, 0, 0)이고, 1초에는 (5, 0, 0)으로 설정되면, 캐릭터는 1초 동안 x축을 따라 이동하게 된다. 추가로 'Add Keyframe'을 선택하면, 원하는 시점에 키프레임을 추가하여 특정 값을 변경할 수 있으며, 두 키프레임 사이의 값은 자동으로 보간되어 설정된다. 이 방식은 영상 편집 프로그램인 프리미어 프로에서 애니메이션을 추가하는 방식과 유사하며, 시간대에 따라 속성값을 조정하여 매끄럽게 변화를 적용할 수 있다.
애니메이션에서 프로퍼티는 여러 개를 중첩하여 설정할 수 있다. 예를 들어, 3D 게임에서 플레이어 캐릭터를 애니메이션화할 때, 팔, 다리 등 신체 부위를 별개의 메시로 만들어 하위 오브젝트로 포함시키고, 애니메이션을 통해 각 부위의 움직임을 조정함으로써 다양한 동작을 표현할 수 있다. 예를 들어, 캐릭터가 뛰는 애니메이션을 만들 때, 팔과 다리의 회전 값, 몸통의 이동 값, 그리고 얼굴 표정 등을 별도로 조정하여 자연스러운 동작을 만들어낼 수 있다.
이와 유사한 방식으로, 애니메이션에서 여러 프로퍼티를 동시에 조정하는 예시를 들어 보겠다. 예를 들어, 한 씬에서 큐브의 회전 값, 메시 렌더러의 컬러 값, 하위 오브젝트인 구체의 y축 값 3가지 프로퍼티를 동시에 애니메이션화한다고 가정하자. 0초에 큐브의 회전 값을 (0, 0, 0), 메시 렌더러의 컬러 값을 빨간색, 구체의 y축 값을 0으로 설정하고, 2초 뒤에는 큐브의 회전 값을 (90, 0, 0), 컬러 값을 파란색, 구체의 y축 값을 5로 설정하면, 애니메이션이 진행되는 동안 큐브는 회전하고, 구체는 y축 방향으로 올라가며, 메시 렌더러의 색상은 빨간색에서 파란색으로 변하게 된다. 이처럼 여러 프로퍼티를 동시에 조정하여 복합적인 애니메이션을 만들 수 있다.
Transition과 Parameters
애니메이션의 전환은 노드를 우클릭한 후 'Make Transition'을 선택하여 화살표 형태로 지정할 수 있으며, 이 화살표는 애니메이션 흐름을 결정하는 중요한 역할을 한다. 화살표의 방향에 따라 애니메이션이 실행되므로, 전환 순서에 유의해야 한다. 예를 들어, 캐릭터가 'Idle' 상태에서 'Run' 애니메이션으로 전환되는 상황을 생각해보자.
- Any State에서 'Run' 애니메이션으로 전환하려면, Any State 노드에서 'Run' 애니메이션으로 가는 화살표를 그린다. 이때, 'Run' 애니메이션이 실행되기 위한 조건을 설정할 수 있다. 예를 들어, 'Run' 버튼이 눌리면 'Idle'에서 'Run'으로 전환되도록 설정한다.
- 'Run' 애니메이션이 끝난 후 다시 'Idle'로 돌아가려면, 'Run' 애니메이션에서 Exit 노드로 향하는 화살표를 추가한다. 이를 통해 'Run' 애니메이션이 끝나면 자동으로 'Idle' 애니메이션으로 복귀하게 된다.
이와 같이, 'Any State'에서 특정 애니메이션으로 전환하고, 해당 애니메이션이 끝나면 다시 기본 상태로 돌아가는 흐름을 설정할 수 있다. 중요한 점은 각 애니메이션 노드가 서로 올바른 순서와 조건에 따라 전환되도록 화살표를 설정해야 한다는 것이다. 예를 들어, 'Run' 애니메이션에서 종료 후 다시 'Idle'로 돌아오려면 'Run'에서 Exit로 연결되는 화살표가 필요하며, 이 전환이 원활하게 이루어지도록 해야 한다.
전환 조건을 설정할 때, 여러 파라미터를 결합하여 복합적인 조건을 만들 수 있다. 예를 들어, Int와 Bool 타입을 사용한 복합 조건을 설정하는 경우를 생각해보자.
- 예시 1: Int와 Bool을 이용한 복합 조건
- Int 타입의 파라미터가 10 이상이고, Bool 타입의 파라미터가 True일 때 전환이 이루어지도록 설정할 수 있다.
- 이 경우, 두 조건이 모두 만족해야만 전환이 발생한다. 즉, Int 값이 10 이상이면서 Bool 값이 True일 때만 해당 애니메이션 전환이 이루어진다.
- 예시 2: Float와 Int를 이용한 복합 조건
- Float 파라미터가 5보다 크고, Int 파라미터가 3 이하일 때 전환이 이루어지도록 설정할 수 있다.
- 이 경우, Float 값이 5보다 크고, Int 값이 3 이하일 때 전환이 발생한다. 두 조건이 동시에 만족해야 하므로, 복합적인 조건을 활용하여 더 정밀한 전환을 만들 수 있다.
이와 같이 여러 파라미터를 결합하여 원하는 조건을 설정함으로써, 애니메이션의 전환 조건을 더 세밀하게 조절할 수 있다.
또한 한 애니메이션의 전환에 Transition을 2개 이상 걸 수도 있습니다. 위 예시의 경우 Idle에서 다시 한번 Make Transition 선택 후 Walk로 이으면 Transition이 중복으로 걸리며, 화살표의 모양도 중첩된 모양으로 변합니다.
예를 들어, Idle 애니메이션에서 이동 속도가 0보다 크거나 특정 버튼 입력 중일 때 Walk 애니메이션으로 전환하고 싶은 경우를 생각해보자. 이때, 두 가지 전환 조건을 설정할 수 있다. 첫 번째 트랜지션은 Float 타입의 파라미터인 이동 속도 값이 0보다 클 때 Walk 애니메이션으로 전환되도록 설정하고, 두 번째 트랜지션은 Bool 타입의 파라미터인 특정 버튼이 눌렸을 때 전환되도록 설정할 수 있다. 이렇게 두 개의 트랜지션을 Idle에서 Walk로 중복하여 설정하면, 각각의 전환 조건이 독립적으로 작동하면서도, 두 조건 중 하나라도 충족되면 Walk 애니메이션으로 전환된다. 인스펙터 창에서는 이 두 가지 전환이 각각 다른 조건을 갖는 두 개의 트랜지션으로 표시되며, 각 트랜지션에 대해 별도의 파라미터를 설정할 수 있어 더욱 세밀한 애니메이션 제어가 가능하다.
3. 스크립트
애니메이터의 제어는 스크립트에서 Animator 컴포넌트에 접근하여 수행할 수 있다. Animator 컴포넌트를 사용하면 애니메이션의 파라미터를 설정하거나 트리거할 수 있다. 예를 들어, SetBool, SetFloat, SetInteger, SetTrigger 함수들을 사용하여 각 파라미터에 값을 설정할 수 있다. 또한, GetCurrentAnimatorStateInfo 함수로 현재 애니메이션 상태를 확인하거나, IsInTransition 함수로 애니메이션이 전환 중인지 확인할 수 있다. 이러한 함수들과 속성들을 활용하면 애니메이션의 흐름을 코드에서 동적으로 제어할 수 있다.
Animator animator;
void Awake()
{
animator = GetComponent<Animator>();
}
void Test()
{
// 애니메이터 관련 함수
// Float형 파라미터 설정
animator.SetFloat("moveSpeed", 5.0f);
// Int형 파라미터 설정
animator.SetInteger("count", 3);
// Bool형 파라미터 설정
animator.SetBool("isWalking", true);
// Trigger 파라미터 설정
animator.SetTrigger("doShoot");
// 애니메이션 속도 조절
animator.speed = 0.5f;
// 애니메이터의 파라미터들
AnimatorControllerParameter[] parameters = animator.parameters;
// 현재 실행중인 애니메이션의 정보
AnimatorStateInfo asInfo = animator.GetCurrentAnimatorStateInfo(0);
bool isNameIdle = asInfo.IsName("Idle");
bool isLooping = asInfo.loop;
}
SetInteger(string name, int value) / SetFloat(string name, float value) / SetBool(string name, bool value)
name 이름의 파라미터의 값을 value로 설정한다. 파라미터 이름과 각 파라미터 타입에 맞는 값을 매개변수로 받으며, 파라미터의 이름과 타입이 함수와 일치해야만 제대로 동작한다.
SetTrigger(string name)
name 이름의 Trigger 파라미터를 작동시킨다. 트리거 파라미터는 호출하는 순간 바로 1회 true로 취급하므로 1회성 애니메이션의 전환에 적합하다.
speed
애니메이터의 애니메이션 재생 속도값이다. float 타입으로, 1.0이 통상 재생속도이며 직접 수정할 수 있다.
parameters
애니메이터가 가지고 있는 모든 파라미터들의 집합이다. AnimatorControllerParameter 타입의 배열이며, 각 원소(파라미터)에 접근하여 이름(name), 타입(type)등의 정보를 확인할 수 있다.
GetCurrentAnimatorStateInfo(int layerIndex)
현재 애니메이터의 상태 정보를 AnimatorStateInfo 타입으로 반환하다. 레이어 인덱스를 매개변수로 받으며, 따로 레이어를 나누지 않았다면 0이 현재 레이어이다. AnimatorStateInfo는 현재 실행중인 애니메이션의 이름을 비교할 수 있는 함수(IsName())와 현재 실행중인 애니메이션의 반복 여부를 확인할 수 있는 속성(loop)을 포함하고 있다.
'Extended Reality > 3D Engine Development' 카테고리의 다른 글
Unity Development [3] : 컴포넌트 기반 아키텍처 (0) | 2024.10.14 |
---|---|
Unity Development [2] : 물리 시뮬레이션 (1) | 2024.10.07 |
Unity Development [1] : 사용자 인터페이스와 바인딩 (1) | 2024.10.07 |
Unity Development [0] : 게임 엔진 아키텍쳐 (0) | 2024.10.07 |