게임/고도엔진 문법

29. [고도 엔진] 플레이어 이동시키기: CharacterBody와 move_and_slide()

밀감감 2026. 7. 17. 12:00
반응형

 

이 카테고리는 고도 엔진(Godot Engine) 관련 문법을 기록하고 저장하기 위해 만든 공간입니다.

 

이번에는 게임에서 가장 먼저 구현하게 되는 기능이자 가장 중요한 뼈대는 바로 '캐릭터 이동'입니다. 슈퍼 마리오처럼 점프를 하거나, 젤다처럼 8방향으로 걸어 다니게 하려면 어떻게 해야 할까요? 고도 엔진(특히 4버전)에서는 CharacterBody(2D/3D) 노드와 move_and_slide()라는 마법의 함수를 사용하여 충돌 처리와 이동을 아주 쉽고 완벽하게 구현할 수 있습니다.

1. CharacterBody 노드: 내 맘대로 조종하는 물리 몸체

게임 속 물체는 크게 두 가지로 나뉩니다. 공처럼 중력과 충돌에 의해 튕겨 나가는 '순수 물리 객체(RigidBody)'와, 벽에 부딪히면 멈추지만 코드로 직접 이동을 제어할 수 있는 '캐릭터 객체(CharacterBody)'입니다.

플레이어나 몬스터처럼 정밀한 조작(원할 때 멈추고, 원할 때 점프하는)이 필요한 노드는 반드시 CharacterBody2D (또는 3D)를 사용해야 합니다.

2. velocity와 move_and_slide(): 환상의 콤보

고도 4의 CharacterBody에는 velocity(속도)라는 변수가 내장되어 있습니다. 이동을 구현하는 기본 공식은 다음과 같이 아주 간단합니다.

  1. 캐릭터가 이동할 방향과 속도를 계산해서 내장 변수인 velocity에 넣는다.
  2. _physics_process 함수 맨 마지막에 move_and_slide()를 딱 한 번 호출한다.

move_and_slide() 함수는 단순히 캐릭터를 이동시키는 것뿐만 아니라, 가다가 벽이나 바닥에 부딪히면 알아서 미끄러지게(Slide) 해주고, 바닥에 닿아있는지(is_on_floor()) 상태까지 자동으로 계산해 주는 엄청난 기능을 가지고 있습니다.

3. 실전! 2D 플랫포머 기본 이동 코드

가장 많이 쓰이는 좌우 이동과 점프, 그리고 중력이 적용된 2D 플랫포머 게임의 기본 뼈대 코드입니다. CharacterBody2D 노드에 스크립트를 생성하면 고도 엔진이 기본적으로 제공해 주는 템플릿과 동일한 구조입니다.

GDScript
 
extends CharacterBody2D

const SPEED = 300.0          # 좌우 이동 속도
const JUMP_VELOCITY = -400.0 # 점프 힘 (위로 올라가야 하므로 마이너스 값)

# 프로젝트 설정에 정의된 기본 중력값을 가져옵니다.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(delta):
    # 1. 중력 적용: 바닥에 닿아있지 않다면(공중에 있다면) 아래로 떨어집니다.
    if not is_on_floor():
        velocity.y += gravity * delta

    # 2. 점프: 바닥에 닿아있고, 점프 키(ui_accept)를 방금 눌렀을 때
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # 3. 좌우 이동: 입력받은 방향(-1, 0, 1)에 속도를 곱합니다.
    var direction = Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        # 키보드에서 손을 떼면 즉시 멈추도록 속도를 0으로 만듭니다.
        velocity.x = move_toward(velocity.x, 0, SPEED)

    # 4. 설정된 velocity 값을 바탕으로 캐릭터를 실제로 이동시키고 충돌을 처리합니다.
    move_and_slide()

4. 이동 후 상태 확인하기: 내가 지금 어딨지?

move_and_slide()가 한 번 실행되고 나면, 캐릭터가 현재 어떤 상태인지 알려주는 유용한 내장 함수들을 사용할 수 있습니다. 이 함수들은 이중 점프(더블 점프)를 구현하거나 벽 타기(Wall Jump) 기능을 만들 때 아주 유용합니다.

  • is_on_floor(): 캐릭터의 발아래가 바닥과 닿아있는가? (true/false)
  • is_on_wall(): 캐릭터의 옆면이 벽과 닿아있는가? (true/false)
  • is_on_ceiling(): 캐릭터의 머리가 천장에 닿아있는가? (true/false)
GDScript
 
func check_state():
    if is_on_wall() and not is_on_floor():
        print("벽에 매달려 있습니다!")
        # 여기에 벽 타기나 슬라이딩 애니메이션 재생 코드를 넣을 수 있습니다.

한눈에 보는 플레이어 이동 핵심 요약

개념 / 함수 기능 설명 실전 게임 개발 활용 예시
CharacterBody2D / 3D 코드로 조종하며 물리(충돌) 법칙의 영향도 받는 특수 노드 플레이어 캐릭터, 추격하는 몬스터, 움직이는 발판(Moving Platform)
velocity CharacterBody에 내장된 속도 벡터(Vector2 또는 Vector3) velocity.x = 300 처럼 값을 대입하여 현재 이동하려는 힘과 방향 설정
move_and_slide() velocity 값을 기준으로 델타 타임(delta)을 자동 계산하여 노드를 이동시킴 충돌 시 멈추거나 미끄러지는(Slide) 처리, 언덕 오르내리기 자동 해결
is_on_floor() move_and_slide() 실행 결과, 바닥에 충돌했는지 판별 점프가 가능한 상태인지(공중 부양 중이 아닌지) 체크할 때 필수 사용
Input.get_axis() 두 액션(왼쪽, 오른쪽) 사이의 값(-1.0 ~ 1.0)을 반환 if문 없이 단 한 줄로 좌우 이동 방향을 구할 때 찰떡궁합
반응형