3 분 소요

플레이어 이동 및 애니메이션 변화주기

플레이어 이동

먼저, 플레이어 이동을 구현해보겠습니다.

이동을 구현하는 방법에는 다양한 방법이 있습니다.

저는 우선 가장 간단하게 이동할 수 있도록 만들어봤습니다.

먼저, 지금은 맵이 좁기때문에 이동을 테스트할 타일을 깔아주겠습니다.

image

타일마다 BOX Collider가 달려있으면 이후에 플레이어 이동시에 불편함이 있을수도 있기때문에

한개의 타일에만 BOX Collider를 달고, BOX Collider의 X방향 크기를 길게 늘려줍니다.

image

Materials 폴더를 하나 생성하여 Create -> 2D -> Physics Material 2D 를 하나 생성해줍니다.

만들어진 파일을 클릭해보면, 우측에 Friction과 Bounciness가 있습니다.

Fricition은 마찰력, Bounciness는 튕김(반동력?) 입니다.

우선, Friction을 0으로 주고 Floor의 Box Collider 부분의 Material에 붙여줍니다.

이렇게 되면 땅의 마찰력이 0으로 설정됩니다.

되었으면 Scripts 폴더를 하나 만들고, PlayerControl 이라는 이름의 C# 스크립트를 생성합니다.

그리고 이 스크립트를 Hierarchy의 Player에 드래그&드롭하여 붙여줍니다.

image

이제, 이동로직을 구현해보겠습니다.

PlayerControl.cs

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

public class PlayerControl : MonoBehaviour
{
    Rigidbody2D rigid;

    public float maxSpeed;

    private void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    void Update()
    {
        //키보드 뗏을때 속도감소(멈춤)
        if (Input.GetButtonUp("Horizontal"))
        {
            //normalized : 단위벡터화
            rigid.velocity = new Vector2(0.5f * rigid.velocity.normalized.x, rigid.velocity.y);

        }
    }
        void FixedUpdate()
    {
        //키보드 방향키 입력으로 움직임
        float h = Input.GetAxisRaw("Horizontal");

        rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);

        if (rigid.velocity.x > maxSpeed) //오른쪽 속도
            rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
        else if (rigid.velocity.x < maxSpeed * (-1))  //왼쪽 속도
            rigid.velocity = new Vector2(maxSpeed * (-1), rigid.velocity.y);
    }
}


AddForce로 힘을 가하기 때문에 키보드를 꾹 누르고있으면 가속도가 붙어 속도가 점점커집니다.

이것을 방지하기위해 maxSpeed라는 임계값을 두어 maxSpeed보다 빠른 속도로 움직이지 못하게 합니다.

저장하고 Hierarchy뷰의 Player를 선택하고 PlayerControl 부분의 maxSpeed 값을 5정도로 설정합니다.

그리고 땅의 마찰력을 0으로 했기때문에 캐릭터가 멈추지 못하고 계속 이동할 것입니다.

따라서 추가적인 작업이 필요합니다.

  • Hierarchy뷰의 Player를 선택하고 Rigid Body 2D 부분의 Linear Drag 값을 2정도로 설정해줍니다. **Linear Drag는 공기 저항입니다.

  • Rigid Body 2D에 Constraints를 눌러보면 Freeze Rotation이 있습니다. Z 부분을 체크해줍니다. **안그러면 캐릭터가 굴러다니는것을 볼 수 있습니다.

다 되었다면 게임을 실행하고 키보드 방향키를 눌러서 이동이 잘 되는지 확인합니다.

애니메이션 전환

이동하는것을 만들고 테스트해보니 조금 이상한 부분이 있을겁니다.

바로 캐릭터의 방향전환이죠. 먼저 좌우로 움직일 때 캐릭터 방향을 전환하는것을 구현해보겠습니다.

방향 전환

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

public class PlayerControl : MonoBehaviour
{
    Rigidbody2D rigid;
    SpriteRenderer spriteRenderer;

    public float maxSpeed;

    private void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        spriteRenderer = GetComponent<SpriteRenderer>();
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    void Update()
    {
        //키보드 뗏을때 속도감소(멈춤)
        if (Input.GetButtonUp("Horizontal"))
        {
            //normalized : 단위벡터화
            rigid.velocity = new Vector2(0.5f * rigid.velocity.normalized.x, rigid.velocity.y);
        }

        //플레이어 방향 전환
        if (Input.GetButtonDown("Horizontal"))
            spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;

    }
    void FixedUpdate()
    {
        //키보드 방향키 입력으로 움직임
        float h = Input.GetAxisRaw("Horizontal");

        rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);

        if (rigid.velocity.x > maxSpeed) //오른쪽 속도
            rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
        else if (rigid.velocity.x < maxSpeed * (-1))  //왼쪽 속도
            rigid.velocity = new Vector2(maxSpeed * (-1), rigid.velocity.y);
    }
}

캐릭터 방향 전환은 SpriteRenderer 부분의 Flip이라는것을 통해 할 수 있습니다.

Flip은 Bool 값으로, 디폴트가 false입니다. 따라서 키보드 입력이 반대가 되면 Flip 값도 반전시켜

방향전환을 해줬습니다.

캐릭터 상태변화

이제 가만히 있을 때와 움직일 때의 애니메이션을 바꾸는 작업을 해보겠습니다.

먼저 저번 포스팅에서 Player의 Idle 애니메이션을 만들었습니다.

이번에는 Player_Walk 라는 이름으로 애니메이션을 만들어 줍니다.

그러고나서 Player의 Animator를 열어보면

image

Player_Walk 라는 상태가 하나 추가된것을 확인할 수 있습니다.

애니메이션을 전환시켜주기위해서 조건이 필요하므로 Parameter의 +버튼을 눌러

isWalking 이라는 Bool형 파라미터를 만들어줍니다.

그리고 Player_Idle를 우클릭하여 MakeTransition을 Player_Walk에,

Player_Walk를 우클릭하여 MakeTransition을 Player_Idle에 연결해줍니다.

image

  • Idle->Walk Transition을 선택한 뒤, Settings 부분의 Transition Duration을 0으로 설정합니다.

  • Conditions 부분의 +버튼을 눌러 isWalking 조건을 추가합니다. 값은 true

  • Has Exit Time 체크를 해제합니다.

Has Exit Time은 애니메이션이 전환될 때 이전 애니메이션을 끝까지진행할 것인지의 여부를 묻는것이기 때문에 체크를 해제해줍니다.

Walk->Idle Transition도 마찬가지로 설정해줍니다. (Condition의 isWalking 값은 false)

이제 스크립트에 적용을 해주면 끝입니다.

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

public class PlayerControl : MonoBehaviour
{
    Rigidbody2D rigid;
    SpriteRenderer spriteRenderer;
    Animator anim;

    public float maxSpeed;

    private void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        spriteRenderer = GetComponent<SpriteRenderer>();
        anim = GetComponent<Animator>();
    }
    // Start is called before the first frame update
    void Start()
    {

    }

    void Update()
    {
        //키보드 뗏을때 속도감소(멈춤)
        if (Input.GetButtonUp("Horizontal"))
        {
            //normalized : 단위벡터화
            rigid.velocity = new Vector2(0.5f * rigid.velocity.normalized.x, rigid.velocity.y);

        }

        //플레이어 방향 전환
        if (Input.GetButtonDown("Horizontal"))
            spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;

        //Walking Animation 설정
        if (Mathf.Abs(rigid.velocity.x) < 0.3f)
            anim.SetBool("isWalking", false);
        else
            anim.SetBool("isWalking", true);
    }

    void FixedUpdate()
    {
        //키보드 방향키 입력으로 움직임
        float h = Input.GetAxisRaw("Horizontal");

        rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);

        if (rigid.velocity.x > maxSpeed) //오른쪽 속도
            rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
        else if (rigid.velocity.x < maxSpeed * (-1))  //왼쪽 속도
            rigid.velocity = new Vector2(maxSpeed * (-1), rigid.velocity.y);
    }
}

지금은 약간의 미끄러짐이 있기때문에 캐릭터의 속도가 0.3 이하가 되었을 때, 캐릭터가 멈췄다고 생각하고 구현했습니다.

가만히 있다가 움직일 때 애니메이션이 전환되는지, 움직이다가 가만히 있을 때 전환되는지 확인합니다.

image

댓글남기기