유니티 기초 강좌: 플레이어 동기화 및 내 플레이어 캐릭터만 제어하기

본 강좌에서는 유니티(Unity)를 사용하여 멀티플레이어 게임에서 플레이어를 동기화하고, 각 클라이언트가 자신의 플레이어 캐릭터만 제어할 수 있도록 하는 방법에 대해 다룰 것입니다. 이 과정에서는 네트워크 프로그래밍 기초부터 시작하여, 유니티의 네트워킹 시스템, 그리고 클라이언트-서버 구조에 대해 설명합니다. 또한, 각 플레이어의 입력을 관리하여 동기화하는 방법도 알아보겠습니다.

1. 유니티 네트워킹 기본 개념

유니티는 멀티플레이어 게임 개발을 쉽게 해주는 강력한 기능을 제공합니다. 네트워크 시스템을 이해하기 위해서는 기본적인 개념 몇 가지를 숙지해야 합니다.

1.1 클라이언트-서버 구조

클라이언트-서버 구조는 네트워크 게임에서 중요한 개념입니다. 클라이언트는 플레이어가 사용할 수 있는 게임의 인스턴스를 의미하며, 서버는 모든 클라이언트의 상태를 관리하는 중앙 시스템입니다.

  • 서버: 모든 게임 진행 상황을 관리하고 클라이언트에게 정보를 전송합니다.
  • 클라이언트: 플레이어의 입력을 처리하고 서버에서 받은 정보를 바탕으로 게임을 진행합니다.

1.2 네트워크 동기화

게임에서 플레이어 캐릭터나 오브젝트의 상태를 동기화해야 합니다. 즉, 모든 클라이언트에 동일한 정보를 제공해야 하며, 이를 통해 원활한 게임플레이를 이루어냅니다.

2. 유니티 설치 및 프로젝트 생성

먼저, 유니티를 설치하고 새로운 프로젝트를 생성해야 합니다. 다음 단계를 따라 진행합니다:

  1. 유니티 허브를 설치합니다.
  2. 원하는 유니티 버전을 다운로드 및 설치합니다.
  3. 유니티 허브에서 ‘새 프로젝트’ 버튼을 클릭하고, 3D 또는 2D 프로젝트를 선택합니다.
  4. 프로젝트의 이름과 저장 위치를 선택한 후 ‘생성’ 버튼을 클릭합니다.

3. 네트워킹 패키지 설정

유니티에서는 다양한 네트워킹 라이브러리를 사용할 수 있지만, 본 강좌에서는 유니티의 MLAPI(Mid-Level API)를 사용할 것입니다. 아래의 과정을 따라 MLAPI를 설치합니다.

  1. 패키지 관리자 (Window > Package Manager)를 열고, 좌측 상단의 ‘+’ 버튼을 클릭합니다.
  2. ‘Git URL’을 선택하고, https://github.com/Unity-Technologies/Mirror.git를 입력한 후 설치합니다.

4. 기본 네트워크 설정

네트워킹 패키지를 설치한 후, 기본 네트워크 설정을 진행해야 합니다. 다음 단계에 따라 진행합니다:

  1. Hierarchy 뷰에서 오른쪽 클릭하여 NetworkManager 오브젝트를 추가합니다.
  2. NetworkManager의 설정 메뉴에서 사용할 씬을 추가합니다.
  3. NetworkManagerHUD를 추가하여 기본 UI를 설정합니다.

4.1 네트워크 매니저 설정

NetworkManager를 설정하여 서버와 클라이언트를 관리할 수 있도록 합니다. 기본적인 동작을 위해 다음 설정을 인지해야 합니다:

  • Maximum Connections: 최대로 연결할 수 있는 클라이언트 수 설정.
  • Network Port: 서버가 사용할 포트 번호 설정.

5. 플레이어 설정

각 플레이어의 캐릭터를 설정해야 합니다. 플레이어 캐릭터는 직접 제어되고, 다른 클라이언트와 동기화되어야 하므로, 이를 위해 프리팹으로 만들어야 합니다.

5.1 플레이어 캐릭터 프리팹 만들기

  1. 새로운 3D 오브젝트로 플레이어 캐릭터를 만듭니다 (예: Cylinder).
  2. 게임 오브젝트에 이동 및 회전을 위한 Rigidbody 컴포넌트를 추가합니다.
  3. 위의 오브젝트를 프리팹으로 만들어 Resources 폴더에 저장합니다.

6. 플레이어 제어 스크립트 작성하기

이제 플레이어 캐릭터를 제어할 수 있는 스크립트를 작성해 보겠습니다. 아래의 코드를 참고하여 PlayerController.cs 스크립트를 구현합니다.

using UnityEngine;
using Mirror;

public class PlayerController : NetworkBehaviour
{
    public float speed = 5f;

    void Update()
    {
        if (!isLocalPlayer)
            return;

        float moveHorizontal = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
        float moveVertical = Input.GetAxis("Vertical") * speed * Time.deltaTime;

        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        transform.Translate(movement);
    }
}

6.1 스크립트 설명

위의 스크립트는 기본적인 WASD/화살표 키 입력을 통해 플레이어를 제어하는 구조입니다. isLocalPlayer를 확인하여 현재 클라이언트의 플레이어 캐릭터만 움직일 수 있도록 설정합니다.

7. 네트워크를 통한 플레이어 동기화

다음 단계는 모든 플레이어 캐릭터가 서버와 통신하여 동기화되도록 만드는 것입니다. 네트워크 상에서 상태를 동기화하기 위해 SyncVarCommand를 사용할 것입니다.

7.1 SyncVar 설정

SyncVar는 변수를 네트워크로 동기화하는 데 사용되며, 서버에서 변경사항이 발생했을 때 클라이언트에 자동으로 반영됩니다.

public class PlayerController : NetworkBehaviour
{
    [SyncVar]
    public Vector3 position;

    void Update()
    {
        if (!isLocalPlayer)
            return;

        float moveHorizontal = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
        float moveVertical = Input.GetAxis("Vertical") * speed * Time.deltaTime;

        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        position += movement; // Update the local position
        CmdUpdatePosition(position); // Command to update the server
    }

    [Command]
    void CmdUpdatePosition(Vector3 newPosition)
    {
        position = newPosition; // Update the server's position
    }
}

8. 결론

이번 강좌에서는 유니티를 기반으로 플레이어 동기화 및 각 플레이어가 자신의 캐릭터만 제어하도록 설정하는 방법에 대해 알아보았습니다. 기본적인 네트워크 환경 구성과 플레이어 스크립팅을 통해 유니티에서 멀티플레이어 게임의 기초를 쌓을 수 있었습니다.

향후 강좌에서는 더욱 다양한 기능을 추가하고, 게임의 복잡성을 높여가며 심화된 내용을 다룰 예정입니다. 궁금한 점이나 피드백이 있다면 댓글로 남겨주세요!