2D 플랫포머 게임 기초

Unity에서 2D 플랫포머 게임의 플레이어 컨트롤러, 카메라 추적, 씬 전환을 구현합니다

Unity에서 2D 플랫포머 게임을 만들기 위한 핵심 스크립트들을 학습합니다. 플레이어 이동, 점프, 카메라 추적, 씬 전환 등 기본적인 게임 메카닉을 구현해봅니다.


게임 구조

2D 플랫포머 게임은 다음 세 가지 핵심 스크립트로 구성됩니다:

스크립트 역할
PlayerController 플레이어 이동, 점프, 애니메이션, 충돌 처리
CameraController 플레이어를 따라가는 카메라
ClearManager 게임 클리어 씬 관리

PlayerController - 플레이어 컨트롤러

플레이어의 이동, 점프, 애니메이션을 제어하는 핵심 스크립트입니다.

전체 코드

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

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rb;
    Animator animator;
    float jumpForce = 680.0f;
    float walkForce = 30.0f;
    float maxWalkSpeed = 2.0f;

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

    void Update()
    {
        // 점프
        if (Input.GetKeyDown(KeyCode.Space) && rb.velocity.y == 0)
        {
            rb.AddForce(transform.up * jumpForce);
            animator.SetTrigger("Jump");
        }

        // 좌우 이동 입력
        int key = 0;
        if (Input.GetKey(KeyCode.RightArrow)) key = 1;
        if (Input.GetKey(KeyCode.LeftArrow)) key = -1;

        // 플레이어 속도
        float speedx = Mathf.Abs(rb.velocity.x);

        // 최대 속도 제한
        if (speedx < maxWalkSpeed)
        {
            rb.AddForce(transform.right * key * walkForce);
        }

        // 좌우 방향 전환
        if (key != 0)
        {
            transform.localScale = new Vector3(key, 1, 1);
        }

        // 애니메이션 속도 조절
        animator.speed = speedx / 2.0f;

        // 화면 밖으로 나가면 게임 재시작
        if (transform.position.x < -3.5f || transform.position.x > 3.5f || transform.position.y < -10f)
        {
            SceneManager.LoadScene("GameScene");
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        Debug.Log("OnTriggerEnter2D: " + collision.gameObject.name);
        SceneManager.LoadScene("ClearScene");
    }
}

핵심 개념 설명

1. 컴포넌트 참조

Rigidbody2D rb;
Animator animator;

void Start()
{
    rb = GetComponent<Rigidbody2D>();
    animator = GetComponent<Animator>();
}
  • Rigidbody2D: 물리 엔진을 통한 이동과 충돌 처리
  • Animator: 스프라이트 애니메이션 제어
  • Start()에서 컴포넌트 참조를 가져옵니다

2. 점프 구현

if (Input.GetKeyDown(KeyCode.Space) && rb.velocity.y == 0)
{
    rb.AddForce(transform.up * jumpForce);
    animator.SetTrigger("Jump");
}
  • Input.GetKeyDown(): 키를 누른 순간 한 번만 실행
  • rb.velocity.y == 0: 땅에 있을 때만 점프 가능 (이중 점프 방지)
  • AddForce(): 물리적 힘을 가해 점프
  • SetTrigger(): 점프 애니메이션 트리거

3. 좌우 이동

int key = 0;
if (Input.GetKey(KeyCode.RightArrow)) key = 1;
if (Input.GetKey(KeyCode.LeftArrow)) key = -1;

float speedx = Mathf.Abs(rb.velocity.x);

if (speedx < maxWalkSpeed)
{
    rb.AddForce(transform.right * key * walkForce);
}
  • Input.GetKey(): 키를 누르고 있는 동안 계속 실행
  • maxWalkSpeed: 최대 속도 제한으로 자연스러운 이동
  • AddForce(): 물리 기반 이동으로 부드러운 가속/감속

4. 방향 전환 (LocalScale 활용)

if (key != 0)
{
    transform.localScale = new Vector3(key, 1, 1);
}
  • localScale.x를 1 또는 -1로 설정하여 스프라이트 좌우 반전
  • flipX 대신 localScale을 사용하면 자식 오브젝트도 함께 반전됨

: SpriteRenderer.flipX를 사용하면 스프라이트만 반전되고, localScale을 사용하면 콜라이더와 자식 오브젝트까지 함께 반전됩니다.

5. 애니메이션 속도 조절

animator.speed = speedx / 2.0f;
  • 플레이어 이동 속도에 비례하여 애니메이션 속도 조절
  • 정지 시 애니메이션도 정지, 빠르게 이동 시 애니메이션도 빨라짐

6. 화면 밖 감지

if (transform.position.x < -3.5f || transform.position.x > 3.5f || transform.position.y < -10f)
{
    SceneManager.LoadScene("GameScene");
}
  • 플레이어가 화면 밖으로 나가면 게임 재시작
  • 좌우 경계와 아래 경계를 체크

7. 트리거 충돌 감지

private void OnTriggerEnter2D(Collider2D collision)
{
    SceneManager.LoadScene("ClearScene");
}
  • 골인 지점에 Is Trigger가 체크된 콜라이더를 배치
  • 플레이어가 골인 지점에 닿으면 클리어 씬으로 전환

CameraController - 카메라 추적

플레이어의 Y축 위치를 따라가는 카메라 스크립트입니다.

전체 코드

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

public class CameraController : MonoBehaviour
{
    public GameObject player;

    void Update()
    {
        Vector3 playerPos = player.transform.position;
        transform.position = new Vector3(transform.position.x, playerPos.y, transform.position.z);
    }
}

핵심 개념 설명

public 변수(variable)로 플레이어 참조

public GameObject player;
  • Inspector에서 플레이어 오브젝트를 드래그하여 연결
  • public으로 선언하면 Inspector에서 설정 가능

Y축만 추적

Vector3 playerPos = player.transform.position;
transform.position = new Vector3(transform.position.x, playerPos.y, transform.position.z);
  • X축과 Z축은 카메라의 원래 위치 유지
  • Y축만 플레이어 위치를 따라감
  • 수직 스크롤 플랫포머에 적합

확장 팁: X축도 추적하려면 playerPos.x를 사용하고, 부드러운 추적을 원하면 Vector3.Lerp()를 활용하세요.

부드러운 카메라 추적 (개선 버전)

public class CameraController : MonoBehaviour
{
    public GameObject player;
    public float smoothSpeed = 5.0f;

    void LateUpdate()
    {
        Vector3 targetPos = new Vector3(transform.position.x, player.transform.position.y, transform.position.z);
        transform.position = Vector3.Lerp(transform.position, targetPos, smoothSpeed * Time.deltaTime);
    }
}
  • LateUpdate(): 플레이어 이동 후 카메라 이동 (Update 이후 실행)
  • Vector3.Lerp(): 부드러운 보간으로 자연스러운 카메라 이동

ClearManager - 클리어 씬 관리

게임 클리어 후 재시작을 처리하는 스크립트입니다.

전체 코드

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

public class ClearManager : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            SceneManager.LoadScene("GameScene");
        }
    }
}

핵심 개념 설명

마우스 클릭 감지

if (Input.GetMouseButtonDown(0))
{
    SceneManager.LoadScene("GameScene");
}
  • Input.GetMouseButtonDown(0): 마우스 왼쪽 버튼 클릭
  • 클리어 화면에서 클릭하면 게임 씬으로 돌아감

Build Settings 설정

씬 전환을 사용하려면 File > Build Settings에서 사용할 씬들을 추가해야 합니다:

  1. GameScene - 메인 게임 씬
  2. ClearScene - 클리어 화면 씬

충돌 감지 콜백 정리

Unity 2D 충돌 감지에 사용되는 콜백 함수(function)들입니다:

콜백 함수(function) 설명
OnCollisionEnter2D 물리 충돌 시작
OnCollisionStay2D 물리 충돌 중
OnCollisionExit2D 물리 충돌 종료
OnTriggerEnter2D 트리거 충돌 시작
OnTriggerStay2D 트리거 충돌 중
OnTriggerExit2D 트리거 충돌 종료

Collision vs Trigger: Collision은 물리적 충돌(밀침), Trigger는 통과하면서 감지만 합니다.


Unity 설정 체크리스트(list)

Player 오브젝트

  • Rigidbody2D 컴포넌트 추가
  • Collider2D 컴포넌트 추가 (BoxCollider2D 또는 CapsuleCollider2D)
  • Animator 컴포넌트 추가 (애니메이션 사용 시)
  • PlayerController 스크립트 추가

Camera 오브젝트

  • CameraController 스크립트 추가
  • Inspector에서 player 변수(variable)에 Player 오브젝트 연결

Goal 오브젝트 (골인 지점)

  • Collider2D 컴포넌트 추가
  • Is Trigger 체크

Build Settings

  • GameScene 추가
  • ClearScene 추가

요약

항목 내용
플레이어 이동 Rigidbody2D.AddForce()로 물리 기반 이동
점프 AddForce(transform.up * jumpForce), 땅에 있을 때만 가능
방향 전환 localScale.x를 1 또는 -1로 설정
카메라 추적 Y축만 플레이어 위치 따라감
씬 전환 SceneManager.LoadScene("씬이름")
트리거 감지 OnTriggerEnter2D() 콜백 사용

이 세 가지 스크립트를 조합하면 기본적인 2D 플랫포머 게임의 핵심 메카닉을 구현할 수 있습니다.


← 목차로 돌아가기