6주차 2교시 / 설명과 시연

상태는 Animator가,
시선은 Camera가

Animator는 이동값으로 Idle과 Move를 고르고, Cinemachine은 화면의 추적 여유와 레벨 경계를 관리합니다.

주황색 Idle과 Move 상태가 전환 화살표로 연결되고, 같은 캐릭터를 청록색 카메라 프레임과 안쪽 Dead Zone이 따라가는 모습
ANIMATOR는 상태를 고르고, POSITION COMPOSER는 화면 안의 위치와 추적 감각을 조절합니다.

2교시의 도착점

교수자의 완성 과정을 따라 관찰하며, 3교시 실습에서 스스로 판단할 연결 규칙과 시작 수치를 확보합니다.

  • 01

    Animation Clip, Animator Controller, Animator, Parameter의 책임을 구분합니다.

  • 02

    Speed가 0에 가까운지에 따라 Idle ↔ Move가 즉시 전환되는 이유를 설명합니다.

  • 03

    Dead Zone과 Damping이 카메라의 추적 시작점과 따라가는 감각을 각각 어떻게 바꾸는지 설명합니다.

  • 04

    Cinemachine Confiner 2D가 레벨 밖 화면 노출을 막는 원리를 설명합니다.

60분의 설명과 시연 흐름

애니메이션의 상태 결정부터 카메라의 최종 화면 경계까지, 신호가 흐르는 순서로 진행합니다.

00-60분

상태와 화면을 연결하기

교수자 설명과 화면 시연

  1. 1교시 회수

    Sprite와 Clip을 구분하고, “어떤 Clip을 재생할지 누가 정하는가?”를 묻습니다.

  2. Animator 네 요소

    Clip, Controller, Animator와 Parameter를 데이터, 규칙, 실행기와 증거로 나눕니다.

  3. Idle ↔ Move 전환

    Speed 조건, Has Exit Time과 Transition Duration을 바꾸며 반응 차이를 관찰합니다.

  4. 코드 연결

    이동 입력의 크기를 SetFloat로 전달하고 flipX로 좌우 방향을 표현합니다.

  5. Cinemachine 추적

    Tracking Target, Position Composer, Dead Zone과 Damping을 하나씩 시연합니다.

  6. Confiner와 회수

    화면 모서리가 레벨 경계 밖으로 나가지 않게 만들고 오류를 역추적합니다.

물리 몸체와 보이는 그림을 부모·자식으로 분리합니다

Player 루트는 게임의 위치와 충돌을 책임지고, Visual 자식은 그림과 애니메이션만 책임집니다. Animation Clip에서 루트 Transform을 기록하지 않는 것이 핵심입니다.

ROOT GAMEOBJECTPlayerRigidbody2D, Collider2D, PlayerController
CHILD GAMEOBJECTVisualSpriteRenderer, Animator
ANIMATED PROPERTYSpriteRenderer / SpriteClip이 바꿀 유일한 핵심 속성
TRACKING TARGETPlayer rootCamera는 시각 프레임이 아니라 실제 위치를 추적
안전 규칙 걷기 Clip이 Player 루트의 Position을 기록하면 Rigidbody2D 이동과 애니메이션 이동이 충돌할 수 있습니다. 이번 수업의 Clip은 Sprite만 바꿉니다.

Animator는 조건이 있는 재생 지도입니다

Animation Clip이 하나의 움직임이라면 Animator Controller는 여러 움직임 사이의 길과 교통 규칙입니다.

  1. 01
    Code value

    PlayerController가 이동 입력의 크기를 계산합니다.

  2. 02
    Parameter

    Speed float에 현재 이동 의도의 크기를 전달합니다.

  3. 03
    Transition condition

    Speed가 기준보다 큰지 작은지 비교합니다.

  4. 04
    State

    조건에 맞는 Idle 또는 Move 상태가 활성화됩니다.

  5. 05
    Motion

    활성 상태에 연결된 Animation Clip이 반복 재생됩니다.

전환ConditionHas Exit TimeDuration 시작값기대 결과
Idle → MoveSpeed Greater 0.01Off0-0.05 s입력을 시작하면 기다리지 않고 Move
Move → IdleSpeed Less 0.01Off0-0.05 s입력을 놓으면 기다리지 않고 Idle
Has Exit Time = Off

현재 Clip의 끝을 기다리지 않고 조건이 참이 되는 즉시 전환을 시작합니다. 이동 입력처럼 즉각 반응해야 하는 상태에 적합합니다.

Transition Duration

두 상태를 섞는 시간입니다. Sprite 교체 애니메이션은 긴 혼합보다 0에 가깝게 시작하고 화면 반응으로 조절합니다.

이미 가진 이동값을 Animator의 증거로 보냅니다

새 이동 시스템을 만들지 않습니다. 4주차 PlayerController가 읽은 moveInput을 시각 표현에도 전달합니다.

PlayerController.cs / 화면 표현 연결
[Header("Presentation")]
[SerializeField] private Animator animator;
[SerializeField] private SpriteRenderer spriteRenderer;

private static readonly int SpeedId = Animator.StringToHash("Speed");

private void Update()
{
    moveInput = moveAction.action.ReadValue<Vector2>();
    moveInput = Vector2.ClampMagnitude(moveInput, 1f);

    animator.SetFloat(SpeedId, moveInput.sqrMagnitude);

    if (Mathf.Abs(moveInput.x) > 0.01f)
    {
        spriteRenderer.flipX = moveInput.x < 0f;
    }
}

Animator.StringToHash("Speed")

문자열 이름을 Animator가 빠르게 비교할 수 있는 정수 ID로 한 번 변환해 보관합니다. Controller의 Parameter 이름과 철자가 같아야 합니다.

moveInput.sqrMagnitude

입력이 없으면 0, 있으면 0보다 큰 값입니다. 방향을 버리고 “움직임의 크기”만 상태 판단에 사용합니다.

animator.SetFloat(...)

계산한 값을 Animator의 Float Parameter에 전달합니다. 이 줄은 Clip을 직접 재생하지 않고 전환 조건의 증거만 갱신합니다.

spriteRenderer.flipX

마지막 수평 방향에 따라 렌더링만 좌우 반전합니다. Transform이나 Collider2D는 뒤집지 않습니다.

카메라는 플레이어를 가운데에 붙이는 장치가 아닙니다

좋은 추적은 플레이어가 어디로 움직이는지 읽을 여유를 남기고, 작은 흔들림에는 반응하지 않으며, 필요한 순간에 부드럽게 따라갑니다.

PackageCinemachine 3.1
ProjectionOrthographic
TargetPlayer root
Position ControlPosition Composer
  1. 01

    Create
    Cinemachine Camera

  2. 02

    Track
    Player root

  3. 03

    Compose
    Position Composer

  4. 04

    Tune
    Dead Zone · Damping

  5. 05

    Confine
    Level boundary

설정질문작게 하면크게 하면시작 범위
Dead Zone / Size얼마나 움직여야 카메라가 반응할까?작은 이동에도 곧바로 추적화면 안에서 더 자유롭게 이동0.12-0.20
Damping X / Y얼마나 빨리 따라잡을까?즉각적이고 단단함느리고 무거우며 지연됨0.3-0.7
Screen Position화면의 어디에 두고 싶은가?중앙에서 시작하고 게임의 진행 방향에 따라 이동(0, 0)
수치는 출발점 Dead Zone은 추적을 시작하는 여유이고 Damping은 따라가는 반응 시간입니다. 둘을 한꺼번에 바꾸지 말고 하나씩 비교합니다.

카메라 점이 아니라 화면 전체를 경계 안에 둡니다

Cinemachine Confiner 2D는 PolygonCollider2D의 모양, 카메라의 보이는 크기와 화면 비율을 함께 고려해 화면 가장자리가 레벨 밖으로 나가지 않게 합니다.

LEVEL OBJECTCameraBounds레벨 전체를 감싸는 별도 GameObject
SHAPEPolygonCollider2D카메라가 허용될 2D 영역, Is Trigger On
EXTENSIONCinemachine Confiner 2DCinemachine Camera에 추가
BOUNDING SHAPE 2DCameraBounds ColliderExtension이 계산에 사용할 외곽선
CHARACTER COLLIDER

Player가 벽을 통과하지 않게

게임 오브젝트의 물리 충돌을 계산합니다. 크기는 Player 몸체에 맞춥니다.

CAMERA CONFINER

화면이 레벨 밖을 보지 않게

보이는 사각형 전체를 제한합니다. 레벨 외곽을 따라 훨씬 크게 만듭니다.

교수자 시연은 다섯 문장으로 확인합니다

각 단계 뒤 Play Mode에서 한 가지 결과만 확인합니다. 마지막에 모든 기능을 한꺼번에 확인하지 않습니다.

  1. A
    Clip

    Idle과 Move를 각각 선택했을 때 Preview에서 반복 재생됩니다.

  2. B
    Animator

    입력을 누르면 Speed가 커지고 Move 상태가 즉시 활성화됩니다.

  3. C
    Facing

    왼쪽·오른쪽에서 Sprite만 반전되고 Collider2D 모양은 유지됩니다.

  4. D
    Follow

    작은 이동은 Dead Zone 안에서 허용되고, 벗어나면 카메라가 부드럽게 따라갑니다.

  5. E
    Boundary

    Player가 네 모서리로 가도 Game View에 레벨 밖 배경이 드러나지 않습니다.

MOVE INPUTSPEEDSTATESPRITECAMERABOUNDARY

증상과 책임을 먼저 연결합니다

오류가 보인 위치와 원인이 있는 위치는 다를 수 있습니다. 가장 가까운 신호부터 확인합니다.

이동하지만 계속 Idle입니다

Animator 창에서 Speed 값이 바뀌는지 봅니다. 0이면 SetFloat 호출과 참조를, 값이 바뀌면 Transition Condition과 Parameter 철자를 확인합니다.

키를 놓아도 Move가 끝까지 재생됩니다

Move → Idle 전환의 Has Exit Time이 꺼져 있는지, Condition이 Speed Less 0.01인지 확인합니다. 긴 Transition Duration도 반응을 늦출 수 있습니다.

좌우 반전 때 충돌 경계도 뒤집힙니다

Player Transform의 Scale X를 음수로 바꿨는지 확인합니다. 이번 구조는 Visual의 SpriteRenderer.flipX만 사용합니다.

카메라가 전혀 따라오지 않습니다

Cinemachine Camera가 활성화되어 있는지, Main Camera에 Cinemachine Brain이 있는지, Tracking Target이 Player root인지 확인합니다.

카메라가 매 프레임 떨립니다

Camera가 Player의 자식인지 먼저 봅니다. 자식이면 분리합니다. Position Composer의 Lookahead가 켜져 있다면 0으로 낮춘 뒤 Pivot 떨림과 Damping을 각각 확인합니다.

끝에 가면 레벨 밖이 보입니다

Confiner 2D의 Bounding Shape 2D 연결, PolygonCollider2D 외곽선, Orthographic Size를 순서대로 확인합니다. Scene View가 아니라 Game View에서 판정합니다.

3교시 전에 연결을 말로 복원합니다

도구 이름을 나열하지 말고, 입력에서 최종 화면까지의 원인과 결과를 한 문장으로 이어 봅니다.

Q1. Speed Parameter는 Clip입니까?

아닙니다. Speed는 코드가 전달하는 숫자이며 Transition이 어떤 State로 갈지 판단하는 증거입니다. State가 선택한 Motion이 Animation Clip입니다.

Q2. Has Exit Time을 이동 전환에서 끄는 이유는?

입력 변화가 생겼을 때 현재 Clip의 특정 재생 시점까지 기다리지 않고 즉시 상태를 바꾸기 위해서입니다.

Q3. Dead Zone과 Damping의 차이는?

Dead Zone은 카메라가 반응하지 않는 화면 안의 여유이고, Damping은 반응을 시작한 뒤 목표를 따라가는 빠르기입니다.

Q4. Player Collider와 CameraBounds는 같은 경계입니까?

아닙니다. Player Collider는 캐릭터의 물리 접촉을, CameraBounds는 카메라 화면 전체가 머물 수 있는 레벨 외곽을 정의합니다.

01 / STATE

코드는 Speed ______만 바꾸고, 전환 조건이 재생할 State를 선택합니다.

02 / FOLLOW

Dead Zone은 카메라가 ______ 않는 영역이고, Damping은 따라가는 ______입니다.

03 / BOUND

Confiner 2D는 카메라의 ______ 가장자리가 Polygon 경계 안에 머물도록 계산합니다.

Unity 공식 자료

Animator는 Unity 6.6, 카메라는 Cinemachine 3.1의 현재 용어를 기준으로 정리했습니다.