유니티로 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 플랫포머 게임에서 일반적으로 사용되는 기본 움직임입니다.

게임 플레이 화면

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

좌우 이동, 점프

더 공부할 자료 - 개발 능력 다양화를 위한 학습의 필요성

유니티 엔진의 대안으로서, 인디 개발자들에게 선풍적인 인기를 끌고 있는 엔진이 바로 고도 엔진입니다. 혹시 고도 엔진을 배워 보려고 하신다면, 다음의 온라인 강의를 체크해 보시기 바랍니다.

초보자를 위한 고도엔진 게임 개발 입문