유니티로 2D 플랫포머 게임 개발에 도전한 초보자 분들 중에, 플레이어의 움직임을 어떤 식으로 구현해야 할 지 막막해 하는 분들이 있습니다. 이런 분들을 대상으로 가장 기본적인 플레이어 움직임을 C# 스크립트로 구현하는 방법을 소개합니다.

프로젝트 생성

제일 먼저 유니티 허브에서 새 2D 프로젝트를 생성합니다.

2D 프로젝트를 생성한다

바닥 스프라이트 생성

다음으로 Assets > Create > 2D > Sprites > Square 를 선택하여 기본 스프라이트를 하나 생성합니다.

Square 스프라이트 생성

이름을 Platform 이라고 지정해 주겠습니다.

이름을 변경한다

드래그해서 씬 하이어라키에 갖다 놓겠습니다. 그리고 가로 스케일을 10으로 늘리겠습니다.

씬에 드래그 앤 드롭

Sprite Renderer에서 색깔을 바꿔 줍니다.

컬러를 바꾼다

플레이어 스프라이트 생성

이제 같은 요령으로 플레이어 스프라이트를 생성하겠습니다. 이번에는 캡슐(Capsule) 모양을 선택합니다.

캡슐 모양 스프라이트 생성

이번에는 이름을 Player 로 지정합니다.

이름을 지정한다

하이어라키 뷰로 드래그해서 갖다 놓습니다. 스케일을 0.5로 줄입니다.

하이어라키로 드래그 앤 드롭

색깔을 바꾸고, 위치를 조정해서 플랫폼 위로 옮깁니다.

색깔 변경 및 위치 조정

잘 보면 게임 오브젝트의 이름이 바뀌지 않은 것을 알 수 있습니다. 이 경우 다음과 같이 이름을 바꿔 줍니다. (안 바꿔도 상관은 없습니다)

이름을 바꾼다

충돌체와 리지드바디 2D 추가

이제 충돌 감지를 위한 컴포넌트들을 추가하겠습니다. 우선 Player 를 선택하고 Add Component 버튼을 누릅니다. Capsule Collider 2D 를 검색해서 추가합니다.

Capsule Collider 2D 추가

리지드바디 2D 도 찾아서 붙여 줍니다.

리지드바디 2D 추가

현재 스프라이트는 캡슐 형태라 나중에 좌우로 움직일 때 넘어질 수 있습니다. 이를 방지하기 위해 Rigidbody 2D 의 Constraints 를 열고 Freeze Rotation 을 체크해 줍니다.

Freeze Rotation 을 체크한다

다음으로는 Platform 을 선택하고, Box Collider 2D 를 붙여 주겠습니다. 여기에는 리지드바디가 필요 없으니 Box Collider 2D 만 붙여 주시기 바랍니다.

Platform에 Box Collider 2D를 붙인다

플레이어 캐릭터 동작 스크립트 작성

이 코드에서는 가장 간단한 플레이어 캐릭터 동작만을 구현합니다. 예를 들어 2D 환경에서 플레이어 캐릭터의 좌우 이동 및 점프 기능은 다음과 같은 방식으로 작성할 수 있습니다.

스크립트 생성

먼저, Unity 스크립트를 생성하고 PlayerMovement라는 클래스를 정의합니다.

PlayerMovement 스크립트 생성

이제 이 스크립트 파일을 더블 클릭해서 비주얼 스튜디오를 열겠습니다. 기본적으로 MonoBehaviour를 상속받은 빈 스크립트가 생성됩니다.

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    void Start()
    {
    }

    void Update()
    {
    }
}

필요한 변수 선언

이제 이동 속도를 나타내는 moveSpeed라는 float 변수를 선언하고 기본값을 5f로 지정합니다.

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;

    void Start()
    {
    }

    ...
}

다음으로, 점프 높이를 결정하는 jumpForce라는 float 변수를 선언하고 기본값을 7f로 지정합니다.

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 7f;

    void Start()
    ...
}

점프 가능 여부를 결정하기 위해 groundCheck라는 Transform 변수와 groundLayer라는 LayerMask 변수를 선언합니다.

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 7f;
    public Transform groundCheck;
    public LayerMask groundLayer;

    void Start()
    ...
}

이제 Rigidbody2D 컴포넌트를 참조할 rb 변수와 땅에 닿았는지 확인하기 위한 isGrounded 불 변수를 선언합니다. 또한, 땅에 닿았는지 확인하는 데 사용되는 원의 반지름을 나타내는 groundCheckRadius 변수를 0.2f로 초기화합니다.

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 7f;
    public Transform groundCheck;
    public LayerMask groundLayer;

    private Rigidbody2D rb;
    private bool isGrounded;
    private float groundCheckRadius = 0.2f;

    
    ...
}

Start 및 Update 메서드 구현

Start() 메서드에서 Rigidbody2D 컴포넌트를 가져와 rb 변수에 할당합니다.

void Start()
{
    rb = GetComponent<Rigidbody2D>();
}

Update() 메서드에서 먼저 groundCheck 위치를 중심으로 반지름이 groundCheckRadius인 원이 groundLayer에 겹치는지 확인하여 isGrounded 변수에 할당합니다.

void Update()
{
    isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
}

이제, 수평 입력을 받아 moveInput 변수에 저장합니다. 이 값은 -1, 0, 또는 1이 될 수 있으며, 각각 왼쪽, 정지, 오른쪽을 나타냅니다.

void Update()
{
    isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);

    float moveInput = Input.GetAxis("Horizontal");
}

Rigidbody2D의 속도를 업데이트하여 캐릭터가 좌우로 움직이도록 합니다. moveInput에 moveSpeed를 곱하고, y축 속도는 그대로 유지합니다.

void Update()
{
    isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);

    float moveInput = Input.GetAxis("Horizontal");
    rb.velocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);
}

마지막으로, 점프 키가 눌렸을 때(Input.GetButtonDown(“Jump”))와 캐릭터가 땅에 있을 때(isGrounded) 점프를 실행합니다. Rigidbody2D의 y축 속도를 jumpForce로 설정하여 캐릭터가 위로 점프하도록 합니다.

void Update()
{
    isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);

    float moveInput = Input.GetAxis("Horizontal");
    rb.velocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);

    if (Input.GetButtonDown("Jump") && isGrounded)
    {
        rb.velocity = Vector2.up * jumpForce;
    }
}

완성된 코드

이제 완성된 코드는 다음과 같습니다.

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

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 7f;
    public Transform groundCheck;
    public LayerMask groundLayer;

    private Rigidbody2D rb;
    private bool isGrounded;
    private float groundCheckRadius = 0.2f;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);

        float moveInput = Input.GetAxis("Horizontal");
        rb.velocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);

        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            rb.velocity = Vector2.up * jumpForce;
        }
    }
}

Player 에 스크립트 추가

이제 하이어라키 뷰에서 Player를 선택하고, 방금 작성한 PlayerMovement 스크립트를 플레이어 캐릭터의 게임 오브젝트에 추가합니다.

플레이어에 스크립트 추가

충돌 체크 기준점 추가

다음으로 캐릭터가 서있을 때 땅에 닿는 부분 근처에 새로운 빈 게임 오브젝트를 생성하고, 이 오브젝트를 groundCheck로 지정합니다. 이 오브젝트는 캐릭터가 땅에 닿았는지 확인하는 기준점 역할을 합니다.

먼저 Player 를 선택하고 마우스 우측 버튼 > Create Empty 를 선택해서 빈 게임 오브젝트를 만듭니다.

빈 게임 오브젝트를 플레이어 자식으로 생성

이름을 groundCheck 로 변경하고 Y 값을 -1로 조정해서 플레이어 캐릭터 바닥에 맞춥니다.

위치를 조정한다

이제 Player 를 선택하고, 방금 만든 groundCheck 를 드래그해서 Player Movement 스크립트의 Ground Check 에 갖다 놓습니다.

groundCheck 연결

Ground 레이어 생성

이제 지면(Platform)에 별도의 레이어 (예: “Ground”)를 지정하여 지상 오브젝트를 분류해야 합니다. 이를 위해 먼저 Platform 을 선택하고, 인스펙터 상단의 Layer 를 선택한 뒤 ‘Add Layer’를 클릭합니다.

레이어를 추가한다

빈 레이어를 찾아 Ground 라는 이름을 지정해 줍니다.

Ground 레이어 생성

다시 Platform 을 선택하고, Layer 를 방금 새로 만든 Ground 로 바꿔 줍니다.

레이어 변경

이제 마지막으로 Player 를 선택한 뒤, PlayerMovement 스크립트에서 Ground Layer 변수에 Ground 레이어를 할당합니다. 이 레이어는 캐릭터가 땅에 닿았는지 판단하는 데 사용됩니다.

Ground Layer 변경

이제 모든 준비가 끝났습니다. 코드가 원하는대로 동작하도록 설정되면, 플레이어는 좌우 방향키나 A와 D 키를 사용하여 좌우로 움직일 수 있습니다. 또한, 스페이스바를 눌러 점프할 수 있습니다. 이때, 캐릭터가 땅에 닿아 있어야만 점프가 가능하며, 점프 중에는 다시 점프할 수 없습니다. 이 기능들은 2D 플랫포머 게임에서 일반적으로 사용되는 기본 움직임입니다.

게임 플레이 화면

다음은 게임을 실행한 장면의 영상입니다.

좌우 이동, 점프