Enemy의 FSM 상태(Idle, Patrol, Chase, Attack)에 맞는 애니메이션을 연결하고, 죽기(Die) 상태를 새로 추가한 과정을 기록한다.
이번 작업의 목표
이번 작업은 Die 상태를 추가하여 FSM 확장하고, 이미 코드에 준비되어 있던 walk, die 애니메이션을 연결할 것이다.
FSM 상태 변화(읽기) → 어떤 애니메이션인지 결정(계산) → Animator에 전달(적용) 이렇게 진행한다.
1. Animator Controller란?
유니티에서 캐릭터 애니메이션은 Animator Controller로 관리한다. 이전 작업에서는 코드로 FSM을 만들었는데, Animator Controller는 이걸 시각적으로 만드는 도구다.
- 상태(State): 하나의 애니메이션 동작 (Idle, Walk, Attack 등)
- 전환(Transition): 상태 간 화살표. "이 조건이면 저 애니메이션으로 바꿔라"
- 파라미터(Parameter): 코드에서 Animator에게 보내는 신호 변수
코드 (Enemy.cs) Animator Controller
━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━
FSM 상태 변경 애니메이션 전환
↓ ↓
animator.SetBool("walk", true) → idle → walk 전환 발동
animator.SetTrigger("attack") → → attack 전환 발동
ㄴ 비교해보면 이른 느낌이라고 보면 된다.
2. 기존 Animator Controller 확인
프로젝트에 이미 LOVEDUCK.controller가 준비되어 있었다. (이름은 LOVEDUCK이지만 엄연히 Enemy(적)이다)

기존에 이미 세 가지 상태가 있었다.
- idle (주황색 = 기본 상태): 가만히 서있기
- walk: 걷기
- attack: 공격
과제 프로젝트에서 제공해 준 사용 가능한 애니메이션 클립들도 있었는데, 다음과 같다.
| 파일 | 용도 |
| idle.anim | 가만히 서있기 |
| walk.anim | 걷기 |
| jump.anim | 점프 (공격 모션으로 사용) |
| stun.anim | 기절 (죽기 모션으로 활용) |
(이 애니메이션들은 Unity 기본 제공이 아님)
3. 파라미터(Parameters) 확인
Parameters 탭을 열어보니 idle, walk, attack 세 파라미터가 있었다.

Bool vs Trigger - 처음에 헷갈렸던 부분
파라미터에는 여러 타입이 있다.
| 타입 | 아이콘 | 동작 | 비유 | 적합한 상황 |
| Bool | ☑ 체크박스 | on/off 유지 | 전등 스위치 | 걷기, 달리기 (계속 유지) |
| Trigger | ● 동그라미 | 한 번 발동 후 자동 꺼짐 | 초인종 | 공격, 점프, 죽기 (한 번 실행) |
| Float | 숫자 | 실수값 | 볼륨 조절 | 이동 속도에 따른 블렌딩 |
| Int | 숫자 | 정수값 | 채널 번호 | 무기 종류 선택 |
기존에는 파라미터가 전부 Trigger로 되어있었는데, 걷기(walk)는 Bool이어야 한다!
왜냐하면!
Trigger로 걷기 애니메이션을 적용하면 걷기가 처음에 적용 되지 않거나 멈춰 있어도 계속 걷기를 하는 등, 부자연스러운 움직임이 일어난다.
그러므로 다음처럼 모션마다 적절한 파라미터를 사용하는 것이 좋다.
걷기 = "걷는 동안 계속" 재생 → Bool (on/off 유지)
코드: animator.SetBool("walk", true) // 걷기 시작
animator.SetBool("walk", false) // 걷기 멈춤
공격 = "한 번만" 실행 → Trigger (자동 꺼짐)
코드: animator.SetTrigger("attack") // 공격! 알아서 꺼짐
나는 기존 walk 를 지우고 Bool Parameters을 가진 walk 를 재생성하여 이 문제를 해결했다.
계속 유지되는 동작(걷기, 달리기)은 Bool
한 번 실행되는 동작(공격, 죽기, 점프)은 Trigger
일단 이렇게 이해하기로 했다.
4. Die 상태 추가하기
die 파라미터 추가
Parameters에서 + → Trigger → 이름 die
(죽기는 한 번만 실행되니까 Trigger로 설정)
die 상태 만들기
Animator 창 빈 공간 우클릭 → Create State > Empty → 이름 die
상태를 선택하고 Inspector의 Motion 항목에 stun 애니메이션을 연결했다.

Motion이란? "이 상태일 때 어떤 애니메이션을 재생할지" 지정하는 것.
die 상태 = stun(기절) 애니메이션을 재생.
Any State → die Transition 추가
Any State에서 die로 화살표를 연결했다.

설정은
- Has Exit Time: 체크 해제 (현재 애니메이션이 끝나길 기다리지 않고 즉시 전환, 총을 맞았는데 걷다가 죽으면 어색하니까ㅎㅎ)
- Conditions: die 트리거 (Parameters 가 Trigger 이므로 조건이 충족되면 발동)
Any State란? "어떤 상태에 있든" 이 전환이 가능하다는 뜻.
죽는 건 걷는 중이든, 공격 중이든, 언제든 발생할 수 있으니까!
5. Transition(전환) 조건 설정
idle → walk

Conditions: walk = true
→ 코드에서 animator.SetBool("walk", true)가 호출되면 이 전환이 발동
walk → idle

Conditions: walk = false (또는 idle 트리거)
→ 코드에서 animator.SetBool("walk", false)가 호출되면 이 전환이 발동
6. Enemy.cs 코드 수정
FSM에 Die 상태 추가
public enum State
{
None,
Idle,
Patrol,
Chase,
Attack,
Die // 새로 추가!
}
상태 초기화에서 애니메이션 신호 보내기
switch (state)
{
case State.Idle:
_agent.ResetPath();
animator.SetBool("walk", false); // 걷기 애니메이션 끄기
break;
case State.Patrol:
_agent.SetDestination(randomDestination);
animator.SetBool("walk", true); // 걷기 애니메이션 켜기
break;
case State.Chase:
_agent.SetDestination(_playerTransform.position);
animator.SetBool("walk", true); // 추적할 때도 걷기
break;
case State.Attack:
_agent.ResetPath();
animator.SetBool("walk", false);
// animator.SetTrigger("attack"); → 이미 Attack() 메서드에 있음
break;
case State.Die:
_agent.ResetPath();
animator.SetBool("walk", false);
animator.SetTrigger("die"); // 죽기 애니메이션 발동
_agent.enabled = false; // 더 이상 이동 불가
break;
}
죽으면 행동 중단
private void Update()
{
_stateTime += Time.deltaTime;
// 죽은 상태면 아무것도 하지 않음
if (state == State.Die) return;
// ... (나머지 FSM 로직)
}
외부에서 호출 가능한 Die() 메서드
public void Die()
{
if (state == State.Die) return; // 이미 죽었으면 무시
nextState = State.Die;
}
나중에 총알이 적에 맞았을 때 enemy.Die()를 호출하면 된다!
7. 코드와 Animator의 관계 정리
Enemy.cs (코드) LOVEDUCK.controller (Animator)
━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━
State = Idle
→ SetBool("walk", false) → walk→idle 전환 발동 → idle.anim 재생
State = Patrol / Chase
→ SetBool("walk", true) → idle→walk 전환 발동 → walk.anim 재생
State = Attack
→ SetTrigger("attack") → →attack 전환 발동 → jump.anim 재생
State = Die
→ SetTrigger("die") → AnyState→die 전환 → stun.anim 재생
핵심은 코드의 FSM과 Animator 상태의 1:1로 대응이다.
코드가 "지금 어떤 상태야"를 알려주면, Animator가 "그러면 이 애니메이션을 재생할게"라고 반응하는 구조인 것.
8. 이번 작업에서 배운 것 요약
1. Animator Controller = 코드 FSM의 시각화 버전
2. 파라미터는 코드 → Animator로 보내는 신호 변수
3. Bool = on/off 유지 (걷기), Trigger = 한 번 발동 (공격, 죽기)
4. 파라미터 타입과 코드의 Set 함수가 일치해야 한다
5. Any State = 어떤 상태에서든 전환 가능 (죽기처럼 언제든 발생하는 것)
6. Has Exit Time 해제 = 현재 애니메이션 끝까지 기다리지 않고 즉시 전환
7. Motion = 상태에 연결된 애니메이션 클립
다음으로 발사체를 만들어 오리를 괴롭히자(?)
'Unity 궁둥이 쪼물쪼물' 카테고리의 다른 글
| 006. 총알에 오브젝트 풀링 적용하기 (0) | 2026.04.06 |
|---|---|
| 005. 발사체(Projectile) 구현 (0) | 2026.04.06 |
| 003. 적 AI 구현 & 맵 꾸미기 (0) | 2026.04.06 |
| 002. CharacterController로 플레이어 움직임 구현 (0) | 2026.04.03 |
| 001. Unity 환경 설정 & New Input System (0) | 2026.04.02 |