2D RPG – 2. 캐릭터 애니메이션 추가

1.애니메이션 만들기

유니티 실행 후 [Window] -> [Animation] 창을 활성화 시킵니다.
캐릭터 객체를 선택하고 [Create]를 선택합니다.

해당 프레임의 위치에 이전에 만들었던 스프라이트 이미지를 드래그로 배치합니다.
재생표시를 눌러 어떻게 재생되는지 확인합니다.

총 8개의 애니메이션이 필요합니다.
걸을 때 모션 4가지(상하좌우), 서있을 때 모션 4가지(상하좌우)
프레임은 60프레임을 사용하며 10프레임 마다 걷기 모션1 -> 서있는 모션 -> 걷기 모션 2-> 서있는 모션 -> 서있는 모션으로 해줍니다.
끝에 서있는 모션을 추가해준 이유는 바로 걷기 모션1이 실행되기까지 딜레이가 필요하기 때문입니다.

2.애니메이터 설정

이제 캐릭터에 애니메이션을 연결하기 위해 애니메이터 설정으로 들어갑니다.
[Window] -> [Animator]

위 사진처럼 복잡한 화면을 볼 수 있는데 모두 삭제 후 [Blend Tree]를 두개 만들어줍니다.
이름은 [Walking Tree], [Standing Tree]로 지정합니다.
파라미터도 추가해줍니다.
필요한 파라미터는 DirX(좌우방향키 체크), DirY(상하방향키 체크), Walking(이동여부 체크)입니다.

Blend Tree 설정

파라미터를 추가한 뒤 [Blend Tree]를 설정해 줍니다.
[Motion]을 추가하고 파라미터 설정과 키입력값에 따른 모션을 연결해 줍니다.

모든 [Blend Tree]를 설정하고 빠져 나옵니다.

Transition 설정

이제 멈춰있을때와 걸을때의 애니메이션을 체크하는 부분입니다.
[Make Transition]으로 서로 연결해주고 Walking 파라미터 값에 따라 실행되도록 해줍니다.
[Has Exit Time] 체크 해제도 필수입니다.

3.스크립트 작성

전체소스

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MovingObject : MonoBehaviour
{
    public float speed; // 움직이는 속도 정의
    private Vector3 vector; // 움직이는 방향 정의

    public float runSpeed; // Shift키 입력시 증가하는 속도
    private float applyRunSpeed; // Shift키 입력시 연산되는 증가 속도
    private bool applyRunFlag = false; // Shift키 입력여부

    public int walkCount; // 방향키 입력시 이동값을 정하기 위한 값
    private int currentWalkCount; // 이동값 리셋을 위한 값

    private bool canMove = true; // 방향키 이동 반복실행 방지를 위한 값

    private Animator animator;


    // Start is called before the first frame update
    void Start()
    {
        // 애니메이터 컴포넌트 가져오기
        animator = GetComponent<Animator>();
    }

    IEnumerator MoveCoroutine()
    {

        // 키입력이 이뤄지는 동안 실행
        // 코루틴은 한번만 실행되고 입력이 이뤄지면 계속 실행
        while (Input.GetAxisRaw("Horizontal") !=0 || Input.GetAxisRaw("Vertical") !=0)
        {
            // Shift키 입력을 확인하여 스피드 값 할당, 입력 여부를 반환            
            if (Input.GetKey(KeyCode.LeftShift))
            {
                applyRunSpeed = runSpeed;
                applyRunFlag = true;
            }
            else
            {
                applyRunSpeed = 0;
                applyRunFlag = false;
            }

            // 변수 vector의 값으로 입력한 방향키 값을 할당 -1 또는 1
            vector.Set(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"), transform.position.z);

            // 입력한 vector 값을 받아 파라미터로 전달 -> 받은 파라미터를 기반으로 애니메이션 실행
            // 동시입력시에 상하키는 기본0이 되도록 설정
            if (vector.x != 0)
            {
                vector.y = 0;
            }
            animator.SetFloat("DirX", vector.x);
            animator.SetFloat("DirY", vector.y);
            animator.SetBool("Walking", true);


            // walkCount 값만큼 반복하여 객체 이동 walkCount(20) * speed(2.4) = 48px
            // 이동시 Shift키 입력여부 확인하여 Speed 값 추가(2.4)
            while (currentWalkCount < walkCount)
            {
                if (vector.x != 0)
                {
                    transform.Translate(vector.x * (speed + applyRunSpeed), 0, 0);
                }
                else if (vector.y != 0)
                {
                    transform.Translate(0, vector.y * (speed + applyRunSpeed), 0);
                }

                // Shift키 입력시 동시에 실행하여 +2씩 증가하는 효과
                if (applyRunFlag)
                {
                    currentWalkCount++;
                }
                currentWalkCount++;

                // 0.01f의 대기시간을 가지고 while문을 반복
                yield return new WaitForSeconds(0.01f);
            }

            // 변수 리셋
            currentWalkCount = 0;
        }
        canMove = true;

        // Walking 값 리셋
        animator.SetBool("Walking", false);
    }

    // Update is called once per frame
    void Update()
    {
        // canMove 변수값에 따라서 작동
        if (canMove)
        {
            // 좌측 방향키면 -1, 우측 방향키면 1, 상측 방향키면 1, 하측 방향키면 -1           
            if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
            {
                canMove = false;
                // 코루틴 실행
                StartCoroutine(MoveCoroutine());
            }
        }
    }
}

이전 소스에서 파라미터를 체크하는 부분과 코루틴 부분이 수정되었습니다.

변수와 Start() 부분

    public float speed; // 움직이는 속도 정의
    private Vector3 vector; // 움직이는 방향 정의

    public float runSpeed; // Shift키 입력시 증가하는 속도
    private float applyRunSpeed; // Shift키 입력시 연산되는 증가 속도
    private bool applyRunFlag = false; // Shift키 입력여부

    public int walkCount; // 방향키 입력시 이동값을 정하기 위한 값
    private int currentWalkCount; // 이동값 리셋을 위한 값

    private bool canMove = true; // 방향키 이동 반복실행 방지를 위한 값

    private Animator animator;


    // Start is called before the first frame update
    void Start()
    {
        // 애니메이터 컴포넌트 가져오기
        animator = GetComponent<Animator>();
    }

애니메이션을 위해 애니메이터 변수를 추가했습니다.

코루틴 부분

    IEnumerator MoveCoroutine()
    {

        // 키입력이 이뤄지는 동안 실행
        // 코루틴은 한번만 실행되고 입력이 이뤄지면 계속 실행
        while (Input.GetAxisRaw("Horizontal") !=0 || Input.GetAxisRaw("Vertical") !=0)
        {
            // Shift키 입력을 확인하여 스피드 값 할당, 입력 여부를 반환            
            if (Input.GetKey(KeyCode.LeftShift))
            {
                applyRunSpeed = runSpeed;
                applyRunFlag = true;
            }
            else
            {
                applyRunSpeed = 0;
                applyRunFlag = false;
            }

            // 변수 vector의 값으로 입력한 방향키 값을 할당 -1 또는 1
            vector.Set(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"), transform.position.z);

            // 입력한 vector 값을 받아 파라미터로 전달 -> 받은 파라미터를 기반으로 애니메이션 실행
            // 동시입력시에 상하키는 기본0이 되도록 설정
            if (vector.x != 0)
            {
                vector.y = 0;
            }
            animator.SetFloat("DirX", vector.x);
            animator.SetFloat("DirY", vector.y);
            animator.SetBool("Walking", true);


            // walkCount 값만큼 반복하여 객체 이동 walkCount(20) * speed(2.4) = 48px
            // 이동시 Shift키 입력여부 확인하여 Speed 값 추가(2.4)
            while (currentWalkCount < walkCount)
            {
                if (vector.x != 0)
                {
                    transform.Translate(vector.x * (speed + applyRunSpeed), 0, 0);
                }
                else if (vector.y != 0)
                {
                    transform.Translate(0, vector.y * (speed + applyRunSpeed), 0);
                }

                // Shift키 입력시 동시에 실행하여 +2씩 증가하는 효과
                if (applyRunFlag)
                {
                    currentWalkCount++;
                }
                currentWalkCount++;

                // 0.01f의 대기시간을 가지고 while문을 반복
                yield return new WaitForSeconds(0.01f);
            }

            // 변수 리셋
            currentWalkCount = 0;
        }
        canMove = true;

        // Walking 값 리셋
        animator.SetBool("Walking", false);
    }

애니메이션의 자연스러운 움직임을 위해 코루틴에 while문이 추가되었습니다.
파라미터 값을 정의해줘서 애니메이션을 실행합니다.

완성화면