07
09
728x90

시작

현재는 위아래로 왔다갔다만 하는 애니메이션 하나뿐이다.

움직일 때 움직이는 모션이 있어야 조작할 맛도 나기에 캐릭터를 조작하면 꾸물꾸물 움직이는 애니메이션으로의 전환 기능을 넣어볼 것이다.

 

Player_Move.png
0.00MB

 

 

캐릭터가 꾸물꾸물 움직이는 애니메이션을 만들 스프라이트 파일이다.

이 역시 대충 만들었기에 기능 사용법 익히는용으로만 생각하자.


스프라이트 설정

이전에 애니메이션 편에서 한 것처럼 16x16픽셀 스프라이트로 사용할 것이기에 위 사진처럼 설정하고 Apply를 누른 후 Sprite Editor를 연다.

 

스프라이트 에디터가 켜지면 Slice를 누르고 위처럼 설정한다.

여기서 중요한 점은 이전과 다르게 일부러 스프라이트 사이사이를 x축으로 1픽셀씩 띄워놓았다.

때문에 Padding옵션의 X값을 1을 주면 

 

위처럼 한 칸씩 띄워서 잘라준다.


애니메이션 만들기

애니메이션 편에서 했던 것처럼 애니메이션을 만든다.

자른 스프라이트 4개를 한번에 선택(컨트롤+클릭으로 하나씩 넣기 혹은 0번누르고 쉬프트 3번클릭 하면 된다)해서 하이어라키 창에 드래그 앤 드롭 한다.

 

애니메이션을 만드는데, 경로는 Assets/Animations에 넣고, 이름은 Charactor_MovePlayer_Move로 하겠다.

 

다 되면 이렇게 애니메이션을 담은 오브젝트 하나가 생성되는데, 실행시켜 보면 빠른 속도로 움직이긴 한다.

이동하는 애니메이션이지만 이동하는게 아니라 펄럭거리는 것 같다. 아오

아무튼 하이어라키 창에서 Player_Move_0을 지워버리고 아래 사진에 있는것도 지운다.

Animations 폴더에서 방금 만든 Player_Move_0을 지운다.(네모모양 연결된걸 지우는거다!!)

저 네모모양 연결된건 "애니메이터(Animator)"라고 해서 애니메이션들을 컨트롤 하는거고

세모모양 달려가는게 "애니메이션(Animation)"이다.

둘을 구분하는게 좋다.

 

우리는 Player_0이라는 애니메이터에서 Charactor_Idle 애니메이션과 Player_Move 애니메이션을 컨트롤할거다. 그래서 Player_Move_0 애니메이터는 필요 없기에 지워버리는 것이다.

 

지운 다음 Player_0 애니메이터를 더블클릭 해서 Animator 편집창을 열어준다.

이 편집창은 컨트롤 하는게 좀 다른데, 기본적으로는 휠로 멀리서 보거나 가까이서 볼 수 있다.

그리고 왼쪽 오른쪽 위 아래등 화면 움직이는건 알트+좌클릭으로 움직이면 된다.

 

이후 저 플로우차트같은게 있는곳에 방금 우리가 만든 Player_Move 애니메이션을 드래그앤 드랍 하면

위처럼 되고, Player_Move를 우클릭 해서 Set as Layer Default State를 누르면 Entry에서 Player_Move로 화살표가 옮겨가며 주황색이 된다.

 

이후 플레이시켜보면

땅으로 들어갔다 나왔다 하던게 꾸물꾸물 움직이는 애니메이션으로 바뀌어 재생된다.

그렇다면 여기서 기억해야 할 것은 애니메이터, 애니메이션의 구분과 애니메이터에서 기본 재생할 애니메이션 설정 방법이다.

다시 말하자면 애니메이션은 우리가 흔히 말하는 움직임을 보여주는 애니메이션

애니메이터는 애니메이션들을 관리, 조작하는 것

애니메이터에서 재생할 애니메이션들을 관리할 수 있다는 것이다.

 

잘 기억해두고, 애니메이션이 너무 빠르고 끊기니까 3편 애니메이션 만들기편처럼 애니메이션 파일을 수정해 준다.

 

Player_Move 애니메이션 파일을 더블클릭 하고

위 사진처럼 돼있는걸 아래 사진처럼 늘려준다.

마름모모양을 눌러서 드래그 하면 움직이고, 컨트롤c 컨트롤v도 먹히기에 쉽게 할 수 있을 것이다.

컨트롤c로 복사했으면 위쪽 숫자부분을 눌러서 커서를 선택해 컨트롤v하면 된다.

 

위 작업을 거치고 다시 실행 해 보면 속도가 느려졌다.


코딩

이제 코딩을 할 차례다.

우리가 해야 할 것은 가만히 있을 때는 Charactor_Idle 애니메이션이 실행되고, 움직일때는 Player_Move 애니메이션이 실행되게 하는 것이다.

 

그 전에 우리는 왼쪽으로 갈 때는 왼쪽을 바라보게 하고 오른쪽으로 갈 때는 오른쪽으로 바라보게 먼저 할 것이다.

이건 크게 하이어라키 창의 Player_0 오브젝트를 가지고 할 것이고, 두 가지 방법이 있다.

첫 번째로 Player_0의 Transform에 있는 Scale X를 음수값을 주는 것이고,

또 하나는 Player_0의 Sprite Renderer에 있는 Flip X값을 체크하는 것이다.

표시된 둘중에 하나만 하면 되는데 쉬우니까 둘 다 해보자.

첫 번째 방법

Transform의 Scale X값을 음수로 줘보자.

Player스크립트를 열고 Move()함수를 아래처럼 수정한다.

단순히 왼쪽 움직일 때, 오른쪽 움직일 때 코드 두 줄 추가했다.

간단히 설명하면

gameObject는 현재 스크립트를 컴포넌트로 담은 오브젝트를 나타내고, 해당 오브젝트의 스케일을 위에서 설명한 대로 조절한 것 뿐이다.

 

코드를 적고 실행시켜서 움직여보면 좌우로 꾸물꾸물 움직이는 것을 확인할 수 있다.

 

두 번째 방법

이번엔 FlipX값을 주는 것이다.

이번에는 첫 번째 방법처럼 gameObject를 사용해서 컴포넌트를 불러오는 것이 아닌 GetComponent를 사용 해 보겠다.(첫 번째 방법도 GetComponent 사용 가능)

GetComponent는 이름 그대로 컴포넌트를 가져오는 것이며, <>안에 가져올 컴포넌트의 타입을 적어준다.

이후 flipX값을 조절하면 되고, 실행시켜 움직여보면 역시 좌우로 바뀌는 것을 볼 수 있다.

 

gameObject와 GetComponent 두 가지 모두 정말 자주 사용하기에 눈에 익혀놓는 것이 좋다.

참고로 gameObject와 GameObject는 앞에 대문자 차이지만 둘이 엄연히 다른 것이기에 이것또한 인지하고있으면 좋다.

 

이제 좌우 플립을 구현했으니까 처음은 가만히 있고 움직이는 것을 구현 해 보자.

 

우선 프로젝트 창의 애니메이터 Player_0을 더블클릭 해서 Charactor_Idle을 기본 애니메이션으로 지정 해 준다.

 

다음으로 Charactor_Idle을 우클릭 해 Make Transition을 누르고 Player_Move에 연결한다.

마찬가지로 Player_Move에서 Charactor_Idle로도 이어준다.

그럼 위 사진처럼 화살표 두 개가 이어지게 되고

탭을 Parameters로 선택 해 +를 눌러 Bool 파라미터를 만들어준다. 이름은 isMove로 지어주겠다.

다 되면 위처럼 되고, 움직일때 true를 줘서 움직이는 애니메이션으로 전환, 멈추면 false를 줘서 가만히 있는 애니메이션으로 전환할 것이다.

다음으로 Character_Idle에서 Player_Move로 가는 화살표를 누른 다음

Has Exit Time을 끄고 Transition Duration을 0으로 준 다음 Conditions에 +를 눌러 위 사진처럼 설정한다.

Has Exit Time과 Transition Duration을 설정하지 않으면 애니메이션을 부드럽게 연결하기 위해 이전 애니메이션과 이후 애니메이션 전환이 바로 이루어지지 않는다.

우리는 스프라이트 교환 방식으로 애니메이션을 실행하기에 해당 기능을 사용하면 부자연스러워 끄는 것이다.

 

마찬가지로 Player_Move에서 Charactor_Idle로 가는 화살표도 설정 한 다음 isMove만 false값으로 바꿔준다.

 

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

public class Player : MonoBehaviour
{
    [Header("이동속도 조절")]
    [SerializeField]
    [Range(1f, 5f)]
    private float moveSpeed = 1f;

    private Animator animator_;

    // Start is called before the first frame update
    void Start() {
        animator_ = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update() {
        
    }

    void FixedUpdate() {
        Move();
    }

    void Move() {
        Vector3 movePosition = Vector3.zero;

        // 왼쪽으로 움직임
        if(Input.GetAxisRaw("Horizontal") < 0) {
            movePosition = Vector3.left;
            GetComponent<SpriteRenderer>().flipX = true;
            animator_.SetBool("isMove", true);
        }
        // 오른쪽으로 움직임
        else if(Input.GetAxisRaw("Horizontal") > 0) {
            movePosition = Vector3.right;
            GetComponent<SpriteRenderer>().flipX = false;
            animator_.SetBool("isMove", true);

        }
        // 안움직임
        else {
            animator_.SetBool("isMove", false);
        }

        transform.position += movePosition * moveSpeed * Time.deltaTime;
    }
}

전체 코드를 참고해서 코드를 추가한다.

아래는 코드설명

더보기
    [Header("이동속도 조절")]
    [SerializeField]
    [Range(1f, 5f)]
    private float moveSpeed = 1f;

먼저 이 부분은 이전에 public으로 이동속도 선언을 했었는데, 위처럼 코드를 바꾸게 되면

public으로 선언하지 않아도 인스펙터 창에서 해당 변수값을 슬라이드로 조절할 수 있게 된다.

    private Animator animator_;

    // Start is called before the first frame update
    void Start() {
        animator_ = GetComponent<Animator>();
    }

이 부분은 Animator 컴포넌트를 가져오기 위해 멤버변수로 선언하고 Update의 첫 프레임에서 호출될 Start부분에서 해당 컴포넌트를 가져온다.

즉, animator_에 스크립트를 컴포넌트로 가진 오브젝트의 애니메이터 컴포넌트를 가져오는 것이다.

animator_.SetBool("isMove", true);
animator_.SetBool("isMove", false);

 이후 Move 함수에 왼쪽, 오른쪽으로 움직일 때와 안움직일 때 애니메이터에서 아까 만든 bool 타입의 isMove파라미터를 조절하게 한다.

다 하고 나서 실행시켜보면 가만히 있을때는 Idle애니메이션이, 움직일 때는 Move애니메이션이 실행되는 것을 볼 수 있다.

 


추가

통일성을 주기 위해 애니메이터, 애니메이션 이름을 아래와 같이 바꾸었다.

따로 설정을 더 할 필요는 없고 선택 후 f2를 눌러 이름을 변경하기만 하면 된다.

애니메이터 Player0 -> Player

애니메이션 Charactor_Idle -> Player_Idle

728x90
COMMENT