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에서 사용할 씬들을 추가해야 합니다:
- GameScene - 메인 게임 씬
- 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 플랫포머 게임의 핵심 메카닉을 구현할 수 있습니다.