본문으로 건너뛰기

Godot 실시간 동기화

Godot 실시간 동기화Godot SDK로 플레이어 상태를 실시간 동기화하는 방법

중급실시간15초읽기 약 3분업데이트 2026-04-14

Godot SDK로 플레이어 상태를 실시간 동기화하는 방법

이 튜토리얼에서 배울 내용
Godot SDK 설치
채널 구독 및 이벤트 처리
상태 전송/수신
플레이어 참가/퇴장 처리

Godot 실시간 동기화

Godot 엔진으로 멀티플레이 게임을 만들 때, ConnectBase 게임 서버를 사용하면 룸 기반 WebSocket 동기화를 표준 흐름으로 구현할 수 있습니다. Godot SDK는 GameClient 노드(autoload 싱글톤)와 signal 기반 이벤트 모델을 제공합니다.

완성된 기능

  • GameClient autoload 로 게임 서버 연결
  • join_room 으로 룸 입장
  • send_action / state_updated signal 로 위치/액션 동기화
  • 플레이어 입장/퇴장 signal 처리

사전 준비

  1. Godot 4.0 이상
  2. ConnectBase 콘솔에서 앱을 만들고 cb_pk_ Public Key 확인
  3. 룸은 JavaScript SDK 또는 REST API 로 사전 생성합니다(Godot SDK는 룸 생성 메서드를 노출하지 않음). 빠른 테스트는 콘솔의 게임 서버 → 룸 메뉴에서 직접 생성

1. SDK 설치하기

GitHub 저장소의 sdk/godot/addons/connect_base_game 폴더를 프로젝트의 addons/ 아래로 복사합니다.

bash
cd your-godot-project
mkdir -p addons
cp -r /path/to/connectbase/sdk/godot/addons/connect_base_game addons/

Godot 에디터를 다시 열어 프로젝트 → 프로젝트 설정 → 플러그인 에서 connect_base_game 을 활성화합니다. 활성화하면 GameClient 이름의 autoload singleton 이 자동 등록됩니다.

2. 연결 & 룸 입장하기

게임이 시작되면 ConnectBase 게임 서버에 연결하고, 사전 생성된 룸에 입장합니다.

player_sync.gd:

gdscript
extends Node

@export var public_key: String = "cb_pk_..."
@export var app_id: String = "your-app-id"
@export var room_id: String = "room_xxx"

func _ready() -> void:
    # GameClient autoload 의 signal 에 연결
    GameClient.connected.connect(_on_connected)
    GameClient.disconnected.connect(_on_disconnected)
    GameClient.state_updated.connect(_on_state_updated)
    GameClient.player_joined.connect(_on_player_joined)
    GameClient.player_left.connect(_on_player_left)
    GameClient.game_error.connect(_on_game_error)

    # 옵션: app_id / public_key 를 GameClient 내부에 세팅 후 connect_to_server 호출
    # (구현 세부는 sdk/godot/addons/connect_base_game/game_client.gd 참고)
    var err = GameClient.connect_to_server(public_key)
    if err != OK:
        push_error("game server connect failed: %s" % err)

func _on_connected() -> void:
    GameClient.join_room(room_id, {"nickname": "Player1"})

3. 내 상태 전송하기

매 물리 프레임마다 입력 또는 위치를 send_input / send_action 으로 전송합니다.

gdscript
@export var is_local_player: bool = true
var _last_send_t: float = 0.0
const SEND_INTERVAL := 0.05  # 50ms — 20Hz

func _physics_process(delta: float) -> void:
    if not is_local_player: return
    if not GameClient.is_connected: return

    _last_send_t += delta
    if _last_send_t < SEND_INTERVAL: return
    _last_send_t = 0.0

    # 입력 전송 (서버가 시퀀스 번호를 매김 — 클라이언트 예측 / reconciliation 단위)
    var seq := GameClient.send_input({
        "pos": {"x": position.x, "y": position.y},
        "vel": {"x": velocity.x, "y": velocity.y},
        "animation": current_animation,
    })

    # 일회성 액션
    if Input.is_action_just_pressed("attack"):
        GameClient.send_action("attack", {"target_id": "player_2", "damage": 25})

💡 매 프레임 전송은 트래픽이 많습니다. 위 예제처럼 SEND_INTERVAL 로 throttle 하거나, 위치 변화가 있을 때만 전송하세요.

4. 다른 플레이어 상태 수신하기

state_updated signal 의 페이로드에서 본인을 제외한 플레이어 상태를 적용합니다.

gdscript
func _on_state_updated(state: Dictionary) -> void:
    var players = state.get("players", [])
    for p in players:
        if p.get("player_id") == GameClient.client_id: continue
        var other := get_player(p.get("player_id"))
        if other == null: continue
        # 부드러운 위치 이동 (lerp)
        var target := Vector2(p.position.x, p.position.y)
        other.position = other.position.lerp(target, 0.3)
        other.play_animation(p.animation)

func _on_player_joined(player: Dictionary) -> void:
    spawn_remote_player(player.player_id, player.get("nickname", ""))

func _on_player_left(player_id: String) -> void:
    despawn_remote_player(player_id)

func _on_disconnected() -> void:
    push_warning("disconnected — try reconnect")

func _on_game_error(err: Dictionary) -> void:
    push_error("GAME_ERROR: %s %s" % [err.get("code", "?"), err.get("message", "")])

5. 테스트하기

  1. Godot 에디터에서 F5 실행
  2. 에디터를 하나 더 열거나 빌드된 게임을 실행하여 2인 테스트
  3. 한쪽에서 캐릭터를 움직이면 다른 쪽에서 _on_state_updated 로 위치가 들어오는지 확인

다음 단계

  • 매치큐 — JS SDK cb.game.enqueueMatch 로 ticket 등록 후 서버 Lua 가 매칭, 결과 room_id 를 클라이언트로 push
  • Lua 스크립트 — 룸 내부 게임 로직(공격 검증, 데미지 계산)을 서버 측 Lua 로 작성 → 클라이언트는 send_action 만 호출
  • send_custom_message — RPC 스타일 메시지 (채팅, 신호) 전송
  • OfflineMode — 네트워크 끊김 대비 addons/connect_base_game/offline_mode.gd 활용

이 튜토리얼이 도움이 됐나요?