Version: 2017.1
멀티플레이어 로비(Multiplayer Lobby)
호스트 이송(Host Migration)

네트워크 클라이언트와 서버

다수의 멀티플레이어 게임은 연결 관리를 위해 NetworkManager를 사용할 수 있지만, 로우 레벨 NetworkServer와 NetworkClient 클래스를 직접 사용할 수도 있습니다.

HLAPI을 사용하는 경우 각각의 게임은 호스팅하는 서버가 있어야 합니다. 따라서 멀티플레이어 게임 참여자는 각각 클라이언트, 전용 서버, 또는 동시에 서버와 클라이언트의 역할을 수행할 수 있습니다. 전용 서버가 없는 멀티플레이어 게임의 경우 동시에 두 역할을 수행하는 경우가 흔합니다.

전용 서버가 없는 멀티플레이어 게임의 경우 게임을 실행하는 플레이어 중 한 명이 그 게임의 “서버”가 됩니다. 해당 플레이어의 게임 인스턴스는 일반 원격 클라이언트가 아닌 “로컬 클라이언트”로 실행됩니다. 로컬 클라이언트는 서버와 동일한 Unity 씬과 오브젝트를 사용하며, 네트워크를 통해 메시지를 보내지 않고 메시지 대기열을 사용하여 내부적으로 통신합니다. 하지만 HLAPI 코드와 시스템의 경우 로컬 클라이언트는 보통 클라이언트로 취급되므로, 클라이언트가 로컬이던 원격이던 거의 동일한 사용자 코드를 사용할 수 있습니다. 이 점을 활용하여 멀티플레이어와 싱글플레이어 모드를 둘 다 지원하는 게임을 단일 코드로 만들 수 있습니다.

멀티플레이어 게임에서 흔한 경우로 게임 네트워크 상태를 관리하는 오브젝트가 있을 수 있습니다. 아래는 NetworkManager 스크립트 시작 부분입니다. 이 스크립트가 게임 시작 씬에 있는 게임 오브젝트에 부착됩니다. 이 스크립트는 단순한 UI와 키보드 처리 기능이 있어서 게임을 여러 네트워크 모드로 시작할 수 있도록 합니다. 실제 게임의 경우에는 “Start Single Player Game”, “Start Multiplayer Game”과 같이 더 시각적으로 개선된 메뉴를 제공하는 것이 좋습니다.

using UnityEngine;
using UnityEngine.Networking;

public class MyNetworkManager : MonoBehaviour {
    
    public bool isAtStartup = true;
    
    NetworkClient myClient;

    void Update () 
    {
        if (isAtStartup)
        {
            if (Input.GetKeyDown(KeyCode.S))
            {
                SetupServer();
            }
            
            if (Input.GetKeyDown(KeyCode.C))
            {
                SetupClient();
            }
            
            if (Input.GetKeyDown(KeyCode.B))
            {
                SetupServer();
                SetupLocalClient();
            }
        }
    }
    
    void OnGUI()
    {
        if (isAtStartup)
        {
            GUI.Label(new Rect(2, 10, 150, 100), "Press S for server");     
            GUI.Label(new Rect(2, 30, 150, 100), "Press B for both");       
            GUI.Label(new Rect(2, 50, 150, 100), "Press C for client");
        }
    }   
}

이 코드는 설정 함수를 호출하여 작업을 진행합니다. 아래는 각 시나리오에 대한 간단한 설정 함수입니다. 이들 함수는 각 시나리오에 대해 서버나 올바른 클라이언트 유형을 생성합니다. 원격 클라이언트의 경우 서버가 동일한 장치(127.0.0.1)에 있다고 가정한다는 점을 상기해야 합니다. 실제 게임의 경우 이 값은 잘 알려진 인터넷 주소나 매치메이킹 시스템에 제공된 값이 됩니다.

    // Create a server and listen on a port
        public void SetupServer()
        {
            NetworkServer.Listen(4444);
            isAtStartup = false;
        }
    
        // Create a client and connect to the server port
        public void SetupClient()
        {
            myClient = new NetworkClient();
            myClient.RegisterHandler(MsgType.Connect, OnConnected);     
            myClient.Connect("127.0.0.1", 4444);
            isAtStartup = false;
        }
    
        // Create a local client and connect to the local server
        public void SetupLocalClient()
        {
            myClient = ClientScene.ConnectLocalServer();
            myClient.RegisterHandler(MsgType.Connect, OnConnected);     
            isAtStartup = false;
        }

이 코드에서 클라이언트는 MsgType.Connect 연결 이벤트에 대해 콜백 함수를 등록하였습니다. 이 함수는 클라이언트가 서버에 연결되는 시점에서 호출되는 HLAPI 내장 메시지입니다. 이 경우 클라이언트의 핸들러 코드는 다음과 같습니다.

    // client function
        public void OnConnected(NetworkMessage netMsg)
        {
            Debug.Log("Connected to server");
        }

이것으로 멀티플레이어 애플리케이션을 작동하게 할 수 있습니다. 이제 NetworkClient.SendNetworkServer.SendToAll를 사용하여 네트워크 메시지를 보낼 수 있지만, 메시지를 보내는 것은 시스템과 상호 작용하는 로우 레벨 방식입니다.

멀티플레이어 로비(Multiplayer Lobby)
호스트 이송(Host Migration)