핵심 정리
| 항목 | 내용 |
|---|---|
| 역할 | Animator Controller와 Avatar를 사용해 상태 전이, 블렌드, 루트 모션을 실행 |
| 언제 쓰는가 | 캐릭터 이동, 공격, 피격, UI 연출, 컷신 오브젝트 애니메이션을 제어할 때 |
| 기준 버전 | Unity 6.5 (6000.5) |
| 핵심 Inspector | Controller, Avatar, Apply Root Motion, Update Mode, Culling Mode |
| 자주 연결되는 API | SetBool, SetFloat, SetTrigger, Play, CrossFade, GetCurrentAnimatorStateInfo, deltaPosition |
Inspector 설정
| 설정값 | 언제 바꾸는가 | 잘못 맞추면 생기는 문제 |
|---|---|---|
| Controller | 상태 머신, 파라미터 세트를 바꿔야 할 때 | 코드의 파라미터 이름과 불일치 |
| Avatar | Humanoid 리타게팅, 본 매핑이 필요할 때 | 자세가 꺾이거나 클립은 재생되는데 포즈가 이상함 |
| Apply Root Motion | 애니메이션 이동량을 실제 이동에 반영할 때 | 스크립트 이동과 중복되어 미끄러지거나 두 번 이동 |
| Update Mode | 물리 타이밍, 일시정지 무시 여부를 맞출 때 | 입력 반응과 재생 타이밍이 어긋남 |
| Culling Mode | 화면 밖 애니메이션 계산을 줄일 때 | 복귀 시 상태나 본 위치가 기대와 다를 수 있음 |
Controller, Avatar
Controller는 어떤 상태 머신과 파라미터를 쓸지 정합니다. Avatar는 리타게팅과 본 구조 해석에 필요합니다. Humanoid 캐릭터인데 Avatar가 어긋나면 애니메이션이 재생돼도 자세가 비정상적으로 꺾일 수 있습니다.
Controller를 바꾸면 파라미터 이름, 레이어, 전이 조건까지 함께 바뀌므로 코드에서 SetTrigger("Attack") 같은 문자열도 같이 점검해야 합니다.
Apply Root Motion
루트 모션을 켜면 애니메이션 클립의 이동량이 실제 오브젝트 이동에 반영됩니다. 근접 전투 캐릭터, 대시, 시네마틱 이동에는 자연스럽지만, 네트워크 동기화나 직접 입력 제어 캐릭터에서는 이동량이 코드와 충돌하기 쉽습니다.
끄면 위치는 스크립트가 주도하고, 애니메이션은 시각만 담당합니다. "움직임은 Rigidbody/CharacterController가, 재생 상태만 Animator가" 구조인 경우가 많습니다.
Update Mode, Culling Mode
Normal은 일반 프레임 기반, Animate Physics는 물리 스텝에 맞춰 애니메이션을 갱신합니다. 물리 기반 리그와 맞물릴 때만 신중히 씁니다. Unscaled Time은 일시정지 UI, 컷신 메뉴처럼 timeScale 영향 없이 돌려야 할 때 필요합니다.
Culling Mode는 화면 밖일 때 애니메이션을 얼마나 계산할지 정합니다. 멀리 있는 군중, 비가시 NPC는 계산을 줄여 성능을 아낄 수 있지만, 보이지 않는 동안에도 뼈 위치가 유지되어야 하는 무기 본이나 히트 판정은 주의해야 합니다.
| 값 | 언제 고르는가 | 주의할 점 |
|---|---|---|
Update Mode = Normal | 대부분의 일반 캐릭터, UI, 연출 오브젝트 | 물리와 1:1로 맞지 않아도 되는 기본 선택 |
Update Mode = Animate Physics | Rigidbody 기반 리그와 물리 타이밍을 맞춰야 할 때 | 입력 반응이 한 박자 무겁게 느껴질 수 있음 |
Update Mode = Unscaled Time | 일시정지 메뉴, timeScale = 0 상태에서도 돌아야 하는 UI 연출 | 게임플레이 애니메이션에 무심코 쓰면 시간감이 어긋남 |
Culling Mode = Always Animate | 화면 밖에서도 본 위치와 상태를 계속 유지해야 할 때 | 가장 비용이 큼 |
Culling Mode = Cull Update Transforms | 화면 밖에서는 본 갱신을 줄이고 싶지만 일부 상태 계산은 남겨둘 때 | 복귀 순간 본 상태가 예상과 다를 수 있음 |
Culling Mode = Cull Completely | 비가시 NPC, 군중처럼 화면 밖 계산을 최대한 줄일 때 | 다시 보일 때 상태 점프처럼 느껴질 수 있음 |
스크립트 연결
| 필드/프로퍼티 | 언제 읽거나 쓰는가 | 주의할 점 |
|---|---|---|
applyRootMotion | 루트 모션을 상황별로 켜고 끌 때 | 이동 시스템과 책임이 겹치지 않게 해야 함 |
deltaPosition / deltaRotation | OnAnimatorMove에서 이동량을 읽을 때 | 루트 모션 기반 시스템에서만 의미가 큼 |
speed | 전체 애니메이션 속도 보정 | 파라미터 기반 블렌드와 체감이 달라질 수 있음 |
runtimeAnimatorController | 컨트롤러를 런타임에 바꿀 때 | 파라미터 세트 호환성 확인 필요 |
| 메서드 | 언제 쓰는가 | 연결 지점 |
|---|---|---|
SetBool() / SetFloat() / SetTrigger() | 상태 전이 파라미터를 바꿀 때 | Update, 입력/상태 로직 |
Play() | 즉시 특정 상태로 보내야 할 때 | 컷신, 디버그, 특수 전이 |
CrossFade() | 현재 상태를 부드럽게 넘길 때 | 상위 상태 머신, 연출 전환 |
GetCurrentAnimatorStateInfo() | 현재 재생 상태 확인 | 공격 종료 판정, 콤보 윈도우 |
OnAnimatorMove() | 루트 모션을 직접 받아 적용할 때 | 루트 모션 제어형 캐릭터 |
Animator 코드는 "파라미터 변경"과 "즉시 상태 전환"을 나눠 읽는 것이 편합니다.
using UnityEngine;
public class PlayerAnimationDriver : MonoBehaviour
{
[SerializeField] private Animator animator;
private static readonly int SpeedHash = Animator.StringToHash("Speed");
private static readonly int AttackHash = Animator.StringToHash("Attack");
public void SetMoveSpeed(float normalizedSpeed)
{
animator.SetFloat(SpeedHash, normalizedSpeed);
}
public void TriggerAttack()
{
animator.SetTrigger(AttackHash);
}
}파라미터 갱신은 Update, 물리 기반 루트 모션 반영은 OnAnimatorMove, 상태 진입/종료 연결은 StateMachineBehaviour나 Animation Event가 흔한 연결 지점입니다.
자주 틀리는 부분
- Controller를 바꿨는데 코드 파라미터 문자열은 예전 이름을 써서 아무 반응이 없을 수 있습니다.
- Root Motion과 스크립트 이동을 동시에 적용하면 미끄러지거나 두 번 움직입니다.
Animate Physics를 무심코 켜면 입력 반응과 시각 타이밍이 달라질 수 있습니다.- 화면 밖에서 애니메이션 계산을 줄였더니 복귀 시 본 위치나 상태가 기대와 달라질 수 있습니다.
관련 컴포넌트
Rigidbody, Audio Source, Light, Unity Animator 파라미터 기본, Timeline과 Playable Director 기본
참고 링크
2 sources