Version: 2017.1
Multiplayer のロビー
ホストマイグレーション

ネットワークのクライアントとサーバー

マルチプレイヤーゲームの多くは NetworkManager を使って接続を管理できるようになりますが、低レベルの NetworkServer や NetworkClient クラスを直接使用することも可能です。

HLAPI 使用の際は、どんなゲームの場合もそのゲームをホストするサーバーが必要となります。したがって、マルチプレイヤーゲームの各参加者は、クライアントにも専用サーバーにも、あるいは同時にサーバーでもクライアントでもある複合体にもなり得ます。複合体として機能するケースは、専用サーバーのないマルチプレイヤーゲームでよく見られます。

専用サーバーのないマルチプレイヤーゲームでは、ゲームを実行しているプレイヤーのうちの一人が「サーバー」として機能します。そのプレイヤーのインスタンスは、通常のリモートクライアントではなく「ローカルクライアント」を実行することになります。ローカルクライアントはサーバーと同じ Unity シーンやオブジェクトを使用し、ネットワークを通じてメッセージを送信する代わりにメッセージキューを利用して内部での通信を行います。しかし、HLAPI のコードとシステムにとってはローカルクライアントも他のクライアントと変わらないため、クライアントがローカルであれリモートであれ、ほぼすべてのユーザーコードは同じになります。このおかげで、マルチプレイヤーモードでもスタンドアローンモードでも動くゲームを同一のコードによって容易に制作することが可能となっています。

マルチプレイヤーゲームでよく見られるパターンは、ゲームのネットワーク状態を管理するオブジェクトをひとつ持たせることです。下記は、NetworkManager スクリプトの開始部分です。このスクリプトはゲームの起動シーンにあるゲームオブジェクトに添付されます。シンプルな UI とキー入力によって、さまざまなネットワークモードでゲームを開始することができます。実際のゲームでは、視覚的にも魅力的にデザインされたメニューに “シングルプレイヤーモードでスタート” や “マルチプレイヤーモードでスタート” などのオプションが表示されたりする所です。

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");
        }
    }   
}

This skeleton of code calls setup functions to get things going. Below are the simple setup functions for each of the scenarios. These functions create a server, or the right kind of client for each scenario. Note that the remote client assumes the server is on the same machine (127.0.0.1), for a real game this would be well known internet address or something supplied by the Match Making system.

    // サーバーを作成し 、ポートで  Listen を呼び出します
        public void SetupServer()
        {
            NetworkServer.Listen(4444);
            isAtStartup = false;
        }
    
        // サーバーを作成し 、サーバーポートに接続します
        public void SetupClient()
        {
            myClient = new NetworkClient();
            myClient.RegisterHandler(MsgType.Connect, OnConnected);     
            myClient.Connect("127.0.0.1", 4444);
            isAtStartup = false;
        }
    
        // ローカルサーバーを作成し、ローカルサーバーに接続します
        public void SetupLocalClient()
        {
            myClient = ClientScene.ConnectLocalServer();
            myClient.RegisterHandler(MsgType.Connect, OnConnected);     
            isAtStartup = false;
        }

このコード内のクライアントは、接続イベント MsgType.Connect 用のコールバック関数を登録しました。これは、クライアントがサーバーに接続されたときに実行される、HLAPI のビルトインメッセージです。この場合は、クライアント上のハンドラー用のコードは以下のとおりです:

    // クライアント関数
        public void OnConnected(NetworkMessage netMsg)
        {
            Debug.Log("Connected to server");
        }

マルチプレイヤーのアプリケーションを作動させるには、これで事足ります。これで、NetworkClient.Send および NetworkServer.SendToAll を使ってネットワークメッセージを送信する準備が整いました。ただし、メッセージ送信によるシステムとの通信方式は、低水準な方式です。

Multiplayer のロビー
ホストマイグレーション