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

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

マルチプレイヤーゲームの多くは 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");
        }
    }   
}

このコードのスケルトンがセットアップ関数を呼び出すことで機能するようになります。下記は、各ケースにおける簡単なセットアップ関数です。これらの関数が、サーバーまたは、それぞれのケースに適切なクライアントを作成します。リモートクライアントは、サーバーが同一マシン上(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.Send および NetworkServer.SendToAll を使ってネットワークメッセージを送信する準備が整いました。ただし、メッセージ送信によるシステムとの通信方式は、低水準な方式です。

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