안녕하세요. 이번 시간에는 Animation 기능을 통해 지난 시간에 구현한 Player 움직임 기능에 생동감을 불어넣어 봅시다.
Animator
Animator Component는 추가된 GameObject에 애니메이션 기능을 추가할 때 주로 사용됩니다. 그리고 애니메이션을 편집하기 위해 Animator Controller라는 파일이 생성해서 등록해 줍니다.
Animator Controller 생성 및 적용
Project 창에서 원하는 위치에 우클릭 -> create -> Animation Controller를 통해 생성할 수 있습니다. 그리고 이 생성한 파일을 추가한 Animator에 넣어주면 됩니다
Animation Clip 생성
Animation Clip은 애니메이션에서 상태 또는 작은 단위라고 하는데요. Jump 또는 Run 등 독립적인 애니메이션을 의미합니다. 아직 Player에 등록된 Animation Clip이 없기 때문에 Animation 창에서 Create 버튼으로 Clip을 생성할 수 있어요. 이후에는 Animation 창에서 드롭다운 메뉴를 통해 또 다른 Clip을 생성할 수 있습니다.
Animation Clip을 한 곳에 모아두면 관리하기 편리하기 때문에 별도의 Animation 폴더를 생성하고, 유후 상태를 의미하는 player_idle clip을 생성했습니다. Animation Clip을 생성하면 Animator Window에서도 자동으로 추가되는 것을 확인할 수 있네요.
Animation Clip은 단일 혹은 여러 개의 Sprite를 프레임 단위로 재생해서 독립적인 애니메이션을 구현합니다. Idle 상태를 만들 때 하나의 Sprit로 표현할 수도 있고 숨 쉬는 모션등을 보여주기 위해 여러 Sprite를 사용해 애니메이션을 구현할 수도 있는데요. Asset에서 제공해 주는 Player Sprite를 보면 player_0부터 player_5까지 유후 상태를 의미하는 Sprite 임을 확인할 수 있네요. 그래서 해당 Sprite들을 선택해서 Animation Window로 드래그 앤 드롭을 해봅시다
Sprite를 올바르게 추가한 뒤 재생 버튼을 누르게 되면 Animation Clip이 재생이 되고 Scean에서 바로 확인할 수 있습니다.
그런데 Sprite 들의 전환이 너무 빠른 느낌이 있는데요. 이럴 때 Animation Clip의 Rate 값을 변경해 속도를 조절할 수 있습니다.
Unity 9.2 버전부터 Rate를 입력해서 변경할 수 있는 기능이 숨겨졌다고 하는데요. 다시 보이게 하는 방법은 Animation 창에서 더 보기 버튼을 눌러 Show Sample Rate를 클릭하시면 됩니다.
Rate는 1초당 그리는 프레임의 수입니다. 10으로 했을 때 가장 부드럽게 Idle 애니메이션이 표현되는 것 같아요!
제공된 Player Sprite를 보면 Player가 오른쪽을 바라보는 Sprite와, 위 쪽을 바라보는 Sripte들을 확인할 수 있는데요. Asset 제작자 분이 위, 아래, 옆 각각 Idle 상태를 만들어주신 것 같네요. 지금까지 배웠던 내용을 복습하며 나머지 Sprtie을 이용해 Animatio Clip으로 만들어봅시다.
Animation State machine
Animation Clip은 애니메이션의 작은 단위라고 했죠. 이제는 특정 논리 구조를 담아 Animation Clip 간의 전환을 구현해 봅시다. Animator 창을 열면 지금까지 추가한 Animation Clip들을 노드 형태로 존재하는 것을 확인할 수 있습니다.
Entry 노드는 Animation 진입 시 실행되는 Default 애니메이션을 가리키는 역할을 가집니다. 그래서 지금 게임을 실행하면 Default인 player_idle_down 애니메이션이 실행되는 것을 확인하실 수 있어요!
Eixt 노드는 Animation의 종료를 의미하는데요. 서브 상태 머신등을 구현할 때 애니메이션 종료를 통해 서브 상태머신을 빠져나갈 때 주로 사용한다고 합니다.
Animation Parameters 추가하기
Animation Parameters는 Animation 전환을 할 때 논리적인 조건을 만들 때 사용합니다. 예를 들어, Bool 타입의 isWalk 변수가 true면 걷기 애니메이션을 실행하고 false면 idle을 실행하라고 할 수 있어요.
걷는 애니메이션을 실행시킬 조건인 isWalk Bool 변수와 플레이어가 바라보는 방향을 의미하는 DirectionX, DirectionY를 설정해 주었습니다.
Blend Tree 생성
Idle과 Walk는 플레이어가 바라보는 방향에 따라 Animation Clip을 각각 가지고 있습니다. 하지만 Idle 또는 Move라는 동일한 행동을 의미하기도 합니다. 때문에 플레이가 움직이는 여부와 이동하는 방향에 따라서 orizontally, up, down 3가지 상태를 반복적으로 전환이 될 텐데요. Blend Tree를 사용하면 이러한 내부 애니메이션 전환을 보다 쉽게 구현할 수 있습니다.
그런 다음 Blend Type을 2D Simple Directional로 설정합니다. 2D Simple Directional는 2가지의 Param으로 Blend Tree 내에 애니메이션 전환을 하겠다는 의미이고 하위 애니메이션들이 모두 다른 방향을 가리킬 때 유용하다고 합니다.
그리고 Motion을 추가합니다. Idle이 바라보는 방향과 초기 애니메이션 총 5가지의 Motion을 추가했습니다. 그리고 각 Motion마다 적절한 DirectionX, DirectionY 값을 설정해 줍니다.
player_idle_horizontally Animation은 오른쪽을 바라보는 애니메이션이었는데요. Player가 왼쪽으로 이동하면 왼쪽을 바라보게 만들어주는 것이 좋겠죠. 이 요구사항을 mirror Animation 기능을 이용해서 구현하려고 했지만 아쉽게도 휴머노이드 애니메이션에서만 가능한 기능이라는 것을 알게 되었습니다. 그래서 왼쪽, 오른쪽 방향 전환은 또 다른 설정으로 해결을 하기로 하고 여기서는 up, down에 애니메이션의 전환 조건으로서 작동되도록 설정합니다.
Animation 전환
Animation 상태 머신에서 Transtion으로 노드 간 전환을 시도할 수 있습니다. 노드 우클릭해서 Make Transition을 클릭해서 전환을 의미하는 방향 화살표를 생성할 수 있습니다. Idle Tree와 Move Tree 서로 간의 Transtion을 생성합시다!
Conditions에 isWalk 변수를 이용해 Transtion을 실행하는 조건을 구현합니다. Idle 상태에서 Move 상태로 전환되는 조건은 isWalk가 true일 때로, 반대의 경우에는 false로 설정해 줍니다.
has Exit Time을 비활성화해서 위 조건이 참이 되면 애니메이션 종료와 관계없이 즉시 전환이 실행해 주도록 합니다.
코드 작성
public class PlayerController : MonoBehaviour
{
//...
Animator animator;
//...
void Start()
{
...
animator = GetComponent<Animator>();
}
Animator 변수를 선언합니다. 그리고 Start 콜백에서 GameObject에 추가된 Animator 컴포넌트 참조를 가져옵니다.
Animator 변수를 통해 우리가 선언한 Animation Param 값을 런타임에 변경할 수 있습니다
void FixedUpdate()
{
if (movementInput != Vector2.zero)
{
bool moveSuccess = TryMove(movementInput);
//...
animator.SetBool("isWalk", moveSuccess);
animator.SetFloat("DirectionX", movementInput.x);
animator.SetFloat("DirectionY", movementInput.y);
} else {
animator.SetBool("isWalk", false);
}
}
FlipX 속성으로 좌우 전환
위 코드로 게임을 실행해 보면 위, 아래, 오른쪽은 정상적으로 동작하지만 왼쪽으로 이동할 때는 Player가 오른쪽을 바라보고 있어 어색함이 있습니다. Sprite Renderer 속성의 FlipX를 통해 이 문제를 해결할 수 있습니다
.
public class PlayerController : MonoBehaviour
{
...
SpriteRenderer spriteRenderer;
...
void Start()
{
...
spriteRenderer = GetComponent<SpriteRenderer>();
}
void FixedUpdate()
{
if (movementInput != Vector2.zero)
{
...
spriteRenderer.flipX = movementInput.x < 0;
...
}
아까처럼 Script에서 SpriteRenderer 컴포넌트를 불러오고 flipX 속성을 반전을 시키고 싶을 때 true로 설정해 줍니다. horizontally 애니메이션이 기본적으로 오른쪽을 바라보기 때문에 movementInput의 x 값이 음수일 때 flipX를 true로 설정해 줍니다.
'Unity' 카테고리의 다른 글
[Unity] 2D Top Down RPG 게임 만들기 - Camera Move (1) | 2023.11.03 |
---|---|
[Unity] 2D Top Down RPG 게임 만들기 - Player Move (1) | 2023.10.20 |
[Unity] 2D Top Down RPG 게임 만들기 - TileMap (0) | 2023.10.16 |
[Unity] 2D Top Down RPG 게임 만들기 - Camera 설정하기 (0) | 2023.10.15 |
[Unity] 2D Top Down RPG 게임 만들기 - Player Prefabs 생성 (0) | 2023.10.14 |