Version: 2021.2
言語: 日本語
クライアントとサーバーへの対処
ホストマイグレーション

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

重要: UNet は非推奨のソリューションになり、現在、新しい Multiplayer とネットワーキングソリューション (Netcode for GameObjects) が開発中です。詳細は、GameObjects Web サイトの Unity Netcode を参照してください。

マルチプレイヤーゲームの多くは Network Manager を使用して接続を管理できますが、低レベルの NetworkServerNetworkClient クラスを直接使用することもできます。

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

専用サーバーのないマルチプレイヤーゲームでは、ゲームを実行しているプレイヤーのうちの 1 人がサーバーとしての役割を果たします。そのプレイヤーのゲームのインスタンスは、通常のリモートクライアントではなく「ローカルクライアント」を実行します。ローカルクライアントはサーバーと同じ 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) にあると想定していることに注意してください。実際のゲームではこれは任意のインターネットアドレスあるいは、マッチメイキングシステム によって提供されるものになります。


// サーバーを作成し 、ポートでリッスンします
    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.SendNetworkServer.SendToAll を使ってネットワークメッセージを送信できます。ただし、メッセージ送信によるシステムとの通信は、低レベルの方法です。

クライアントとサーバーへの対処
ホストマイグレーション