Unity - 2D 플랫포머 : 플레이어 이동하기

TXMAY·2023년 7월 22일

Unity 튜토리얼

목록 보기
15/33
post-thumbnail

이번 강좌는 플레이어 이동하기에 관한 강좌다.


물리 이동

스크립트 파일을 생성한 후 다음과 같은 코드를 작성한다.

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

public class PlayerMove : MonoBehaviour
{
    Rigidbody2D rigid;

    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");

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

Player에 파일을 놓고 실행하면 방향키 좌우키를 누르면 좌우로 이동한다.
다만 이 코드에는 문제가 있는데 FixedUpdate에서 AddForce로 움직였기 때문에 방향키를 꾹 누르면 1초에 50번 AddForce를 했기 때문에 계속해서 빨라진다. (가속을 무한으로 받는다)
그렇기에 가속에 제한을 걸어야 한다.
다음과 같은 코드를 추가한다.

...

void FixedUpdate()
{
	...
    
    if (rigid.velocity.x > maxSpeed)
    {
        rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
    }
    else if (rigid.velocity.x < -maxSpeed)
    {
        rigid.velocity = new Vector2(-maxSpeed, rigid.velocity.y);
    }
}
...

Inspector에서 Max Speed를 지정하면 더 이상 속도가 오르지 않고 일정한 속도로 움직인다.

저항 설정

'2D - Physics Material 2D'를 만든 후 Friction 값을 0으로 설정한다. (다음 강좌에서 사용한다)
생성한 바닥 오브젝트에 Collider의 Material에 넣는다.
이러면 Player가 움직이면 그 방향으로 계속해서 미끄러지는 것처럼 이동한다.
하지만 이렇게 되면 이동하는 데 불편함이 있으므로 Player에서 저항을 설정해 준다.
Rigidbody에서 Linear Drag의 값을 바꿔준다.
Linear Drag : 공기 저항, 이동 시 속도를 느리게 해줌
그래도 아직 약간에 미끄러짐이 있다.
키보드를 누르지 않으면 빠르게 멈추도록 다음과 같은 코드를 추가한다.

 void Update()
    {
        if (Input.GetButtonUp("Horizontal"))
        {

            rigid.velocity = new Vector2(rigid.velocity.normalized.x * 0.5f, rigid.velocity.y);
        }
    }

normalized : 벡터 크기를 1로 만든 상태(단위벡터)
키보드에서 손을 떼면 빠르게 멈추게 된다.
Rigidbody가 있는 오브젝트들은 'Constraints - Freeze Rotation - Z'를 활성화해야 한다.
Freeze Rotation : 해당 축으로의 회전을 얼리는 옵션

애니메이션 순환

Player가 좌우로 이동은 하지만 애니메이션은 바뀌지 않는다.
좌우로 이동할 때, 이동하는 애니메이션으로 바꿔보겠다.
우선 플레이어가 이동하는 방향과 바라보는 방향을 똑같이 맞춰야 한다.
'Sprite Renderer - Flip'을 눌러보면 해당 축의 스프라이트 방향이 뒤집힌다.
Flip : 스프라이트를 뒤집는 옵션
이제 코드에서 Flip을 해보겠다.
다음과 같은 코드를 추가한다.

...

SpriteRenderer spriteRenderer;
void Awake()
{
    ...
    
    spriteRenderer = GetComponent<SpriteRenderer>();
}

void Update()
{
    ...
    
    if (Input.GetButton("Horizontal"))
    {
        spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;
    }
}
...

Player가 이동하는 방향을 바라보게 된다.
이제 애니메이션을 변경해 보겠다.
'Player' Animator 컨트롤러 파일을 실행한 후 Entry와 연결된 기본 애니메이션을 우클릭한 후 'Make Transition'을 클릭한다.
Transition : 애니메이션 상태를 옮겨가는 통로
그러면 화살표가 있는 직선이 생기는데 걷는 애니메이션에 연결한다.
상단에 'Parameters'를 클릭한 다음 +버튼을 누르면 애니메이터 매개변수의 타입(Float, Int, Bool, Trigger)이 나온다.
애니메이터 매개변수 : 상태를 바꿀 때 필요한 변수
Bool 타입 변수를 생성한 후 이름을 'isRunning'으로 바꾼다.
그다음 기본 애니메이션과 이동 애니메이션 사이에 화살표가 있는 직선을 클릭한 후 'Conditions'에서 +를 누른 후 'isRunning - true'로 설정한다. (isRunning이 true면 이동 애니메이션으로 바꾼다)
그리고 바로 위에 두 애니메이션의 타임바가 있는데 파란색으로 지정된 범위의 시작점과 종료점을 일치시키고(두 애니메이션을 자연스럽게 바꾸게 하는 기능이지만 2D이기 때문에 사용하지 않는다) 'Has Exit Time'을 비활성화한다.
Has Exit Time : 애니메이션이 끝날 때까지 상태를 유지
정리하면 다음과 같이 설정한다.

  • 매개변수 설정
  • 겹구간 닫기
  • Has Exit Time 비활성화

이제 이동 애니메이션에서 똑같이 'Make Transition'을 한 후 기본 애니메이션과 연결하고 설정한다.
이번에는 이동중이 아닐 때 애니메이션이 바뀌어야 하므로 'isRunning - False'로 설정하고 나머지는 동일하게 설정한다.
이제 isRunning 값을 바꾸기 위해 다음과 같은 코드를 추가한다.

...

Animator anim;

void Awake()
{
    ...
    
    anim = GetComponent<Animator>();
}

void Update()
{
    ...
    
    if (Mathf.Abs(rigid.velocity.x) < 0.3)
    {
        anim.SetBool("isRunning", false);
    }
    else
    {
        anim.SetBool("isRunning", true);
    }
}
...

Mathf : 수학 관련 함수를 제공하는 클래스


뭔가 간단한 듯하면서도 어려워 보인다.
그래도 익숙해지면 간단할 것 같다.

profile
게임 개발 공부하는 고양이

1개의 댓글

comment-user-thumbnail
2023년 7월 22일

플레이어 이동에 관한 강좌, 잘 읽었습니다. 이해가 쉽게 설명해주셔서 공부하는 데 도움이 되었습니다.

답글 달기