본문으로 건너뛰기

Unity 멀티플레이 게임 만들기

Unity 멀티플레이 게임 만들기Unity SDK로 실시간 매칭·동기화를 구현하는 멀티플레이 가이드

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

Unity SDK로 실시간 매칭·동기화를 구현하는 멀티플레이 가이드

이 튜토리얼에서 배울 내용
Unity SDK 설치 및 초기화
룸 생성/참여 시스템
플레이어 상태 실시간 동기화
위치 보간 (Lerp)

Unity 멀티플레이 게임 만들기

멀티플레이 게임의 네트워크 프로토콜·매칭·상태 동기화를 직접 구현하면 코드 양이 폭주합니다. ConnectBase Unity SDK 의 GameClient MonoBehaviour 컴포넌트를 사용하면 WebSocket 연결, 입력/위치 동기화, 클라이언트 예측, 보간 까지 표준 동작이 묶여 있어 게임 로직에만 집중할 수 있습니다.

완성된 기능

  • ConnectBase.GameServer.GameClient 컴포넌트로 게임 서버 연결
  • JoinRoom 으로 룸 입장 (룸 생성은 JS SDK / REST 에서 사전 처리)
  • SendPosition / OnStateUpdate 로 위치 동기화
  • 자동 클라이언트 예측 + 보간 (NetworkTransform / ClientPrediction 보조 컴포넌트)

사전 준비

  1. Unity 2021.3 LTS 이상
  2. ConnectBase 콘솔에서 앱을 만들고 cb_pk_ Public Key 확인
  3. 룸 자체는 JavaScript SDK 또는 REST API 로 생성합니다 (Unity SDK 는 CreateRoom 을 노출하지 않음 — 권한이 분리되어 있어서 서버측 또는 다른 클라이언트가 발급). 빠른 테스트라면 콘솔의 게임 서버 → 룸 메뉴에서 직접 생성하세요.

1. SDK 설치하기

Unity 에디터에서:

  1. 상단 메뉴 Window → Package Manager 클릭
  2. 왼쪽 상단 + 버튼 → Add package from git URL 선택
  3. 아래 URL을 붙여넣고 Add 클릭:
https://github.com/connect-base/connectbase.git?path=/sdk/unity

설치 후 using ConnectBase.GameServer; 네임스페이스를 사용할 수 있습니다.

2. GameClient 컴포넌트 붙이기

씬에 빈 GameObject 를 만들고 GameClient 컴포넌트를 추가합니다. 컴포넌트의 Public Key 필드에 cb_pk_ 키를 입력합니다.

GameManager.cs:

csharp
using ConnectBase.GameServer;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    [SerializeField] private string roomId = "room_xxx";

    async void Start()
    {
        var client = GameClient.Instance;
        if (client == null)
        {
            Debug.LogError("GameClient 컴포넌트가 씬에 없습니다");
            return;
        }

        client.OnConnected += () => Debug.Log("게임 서버 연결됨");
        client.OnPlayerJoined += player => Debug.Log($"입장: {player.PlayerId}");
        client.OnPlayerLeft += playerId => Debug.Log($"퇴장: {playerId}");
        client.OnStateUpdate += state => Debug.Log($"상태 업데이트: {state.Players.Length} players");
        client.OnGameError += err => Debug.LogError($"GAME_ERROR: {err.Code} {err.Message}");

        // Public Key 는 인스펙터에서 설정했다면 인자 없이 호출 가능
        bool ok = await client.Connect();
        if (!ok) return;

        // 사전 생성된 룸에 입장 (룸 생성은 JS SDK / REST 로 처리)
        await client.JoinRoom(roomId, new System.Collections.Generic.Dictionary<string, string> {
            { "nickname", "Player1" }
        });
    }
}

💡 GameClient 는 MonoBehaviour 싱글톤(Instance) 입니다. 다른 스크립트에서 GameClient.Instance.SendPosition(...) 로 호출하세요.

3. 위치 동기화 (자동 처리)

가장 쉬운 방법은 동기화할 GameObject 에 NetworkTransform 컴포넌트를 추가하는 것입니다. 매 FixedUpdate 마다 SendPosition 이 자동 호출됩니다.

직접 호출 패턴도 가능합니다:

PlayerController.cs:

csharp
using ConnectBase.GameServer;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private bool isLocalPlayer;

    void Update()
    {
        if (!isLocalPlayer) return;
        if (!GameClient.Instance.IsConnected) return;

        // 내 캐릭터의 현재 위치/회전을 서버로 전송
        GameClient.Instance.SendPosition(transform.position, transform.rotation);

        // 일회성 액션 (공격, 아이템 사용 등)
        if (Input.GetKeyDown(KeyCode.Space))
        {
            GameClient.Instance.SendAction("attack", new {
                target_id = "player_2",
                damage = 25
            });
        }
    }
}

SendInput 은 입력 시퀀스 번호와 함께 전송되어 클라이언트 예측 / 서버 reconciliation 의 단위가 됩니다.

4. 다른 플레이어 보간

다른 플레이어 GameObject 에 ClientPrediction 또는 NetworkTransform 컴포넌트를 붙이면 OnStateUpdate 의 위치 차이를 자동 Lerp 합니다. 직접 구현 시:

csharp
client.OnStateUpdate += state => {
    foreach (var p in state.Players)
    {
        var obj = FindPlayer(p.PlayerId);
        if (obj == null) continue;
        // 부드러운 위치 이동 (순간 이동 방지)
        obj.transform.position = Vector3.Lerp(
            obj.transform.position, p.Position, Time.deltaTime * 10f);
    }
};

5. 테스트하기

  1. Unity 에디터에서 Play 버튼 — 첫 클라이언트가 연결됩니다
  2. 콘솔에서 "게임 서버 연결됨" → "입장: ..." 로그 확인
  3. 같은 빌드를 한 번 더 실행하거나 다른 기기에서 동일 roomId 로 입장 → 두 클라이언트가 위치를 주고받습니다

다음 단계

  • 매치큐 — JS SDK cb.game.enqueueMatch 로 ticket 등록 후 서버 Lua 가 매칭, 결과 roomId 를 Unity 로 push
  • Lua 스크립트 — 룸 안의 게임 로직(공격 검증, 데미지 계산)을 서버 측 Lua 로 작성 → 클라이언트는 SendAction 만 호출
  • NetworkTransform 커스터마이즈 — 보간 가중치, 압축, 보낼 빈도 조정
  • SendCustomMessage — RPC 스타일 메시지 (채팅, 신호) 전송

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