Unity 同士のデータ送受信で Mirror の最小構成 (2021/7確認版)

本記事は 2019/12 に書いた記事を 2021/7 に確認した内容で再投稿しています。
・Unity LTS version 2020.3.5f1
・Mirror 42.2.12

古いバージョンをご利用の方は、過去の記事を参考にしてください。
Unity 同士のデータ送受信で Mirror の最小構成

Mirror

ネットワーク上にある Unity 同士でデータの送受信を行う際、多くの開発者が Mirror を利用しています。AssetStore より Mirror をインポートすると、多くのサンプルがあるので慣れると使い方に悩むことはありませんが、初めて利用するユーザにとっては Mirror がどのような仕組みなのか理解に時間がかかるかもしれません。

また、例えば Mirror のサンプルの Basic などで紹介されている方法は、同じシーンを利用していなければ、「 Unknown message ID 」のエラーが発生します。もちろん異なるシーン同士でもデータのやり取りが発生することがあるでしょう。

そこで今回は Mirror を利用し、サーバからクライアントにデータを送信する最小構成を紹介したいと思います。最小構成の場合、たった3つのスクリプトを用意するだけで動作を確認することができます。以降は新規プロジェクトを作成してからの手順となります。

AssetStore より Mirror をインポート

AssetStore にて Mirror を検索し、「マイアセットに追加する」ボタンを押下します。 そして Unity の Package Manager より Mirror を選択し、インポートしましょう。

ServerシーンとClientシーンの準備

ServerシーンとClientシーンは途中まで同じ内容になります。次の手順で各シーンを用意しました。

  1. Project ウィンドウにおいて、新規 Scene を作成し「 Server 」にリネーム
  2. Hierarchy ウィンドウにおいて、空のオブジェクトを2つ追加しそれぞれ「 Network 」「Sample」にリネーム
  3. 2.で作成した Network オブジェクトに、 Inspector ウィンドウより「 Network Manager HUD 」コンポネントを追加(自動で Network Manager と Telepathy Transport も追加されます)
  4. Project ウィンドウにおいて、「 Server 」シーンを Duplicate (Ctrl + D) し「 Client 」にリネーム

ここまでが前準備になります。一般的な Mirror の利用方法であれば、 Network Manager コンポネント Player Prefab に任意の Prefab を追加しますが、今回の方法では必要ありません。

スクリプトの準備

3つのファイルを用意します。
一つ目は、送受信するデータを定義するクラスです。

SendData 構造体

using Mirror;

[System.Serializable]
public struct SendData : NetworkMessage
{
    public int value;
}

ここでは整数値のみを送受信することにしました。 残りの二つは、サーバとクライアントのためのスクリプトです。

ServerSample クラス

using Mirror;
using UnityEngine;

public class ServerSample : NetworkBehaviour
{
    void Update()
    {
        SendData sendData = new SendData()
        {
            value = Random.Range(0, 10)
        };

        //毎フレームデータ送信
        NetworkServer.SendToAll(sendData);
    }
}

サーバでは、クライアントに対して毎フレームデータを送ります。

ClientSample クラス

using Mirror;
using UnityEngine;

public class ClientSample : MonoBehaviour
{
    void Start()
    {
        //データ受信の準備
        NetworkClient.RegisterHandler<SendData>(ReceivedInfo);
    }
        
    private void ReceivedInfo(SendData receivedData)
    {
        //データ受信時にConsoleに出力
        Debug.Log(JsonUtility.ToJson(receivedData));
    }
}

クライアントでは、起動時にデータ受信の準備を行い、データを受信したら Console ウィンドウに受信したデータを表示するようにしました。

各シーンの Network オブジェクトにスクリプトを追加

Server シーンの Sample オブジェクトに「 ServerSample 」スクリプトを、Client シーンの Sample オブジェクトに「 ClientSample 」スクリプトを追加します。 このとき ServerSample クラスは NetworkBehaviour クラスを継承しているため、自動で NetworkIdentity コンポネントが追加されます。

サーバのビルド・実行

今回の動作確認は、サーバとクライアントが同一PC上にある前提で進めます。またサーバのIPアドレスを指定することで、ネットワーク経由でデータ送受信が可能になります。

今回用意したクライアントは、Consoleにログを出力するように設定しているため、サーバをビルド・実行し、クライアントをUnityEditor上で動かしましょう。

  1. Server シーンを開く
  2. File => Build Settings ... より Build Setting 画面を表示
  3. Scenes In Build に「 Server 」シーンを追加
  4. Build ボタンをクリックし、ビルドを開始
  5. ビルドが完了したら exe ファイルを実行

表示されているボタン類は、 Network Manager HUD コンポネントにより用意されています。こちらはサーバですので、「 LAN Server Only 」をクリックします。

Windows セキュリティの重要な警告が表示されますが、ローカルPCのみで確認するのであれば「キャンセル」を押しても動作しますが、ローカルネットワークで別PCと送受信する場合は、「プライベート ネットワーク」にチェックを入れ「アクセスを許可する」ボタンをクリックしてください。警告画面が閉じると、サーバがスタートします。

クライアントの実行

  1. Client シーンを開く
  2. Unity Editor の実行ボタンをクリック

「 LAN Client 」ボタンの右にあるテキストボックスに「 localhost 」と表示されていることを確認します。ローカルネットワークの場合は、サーバの IP アドレスを入力してください。そして「 LAN Client 」ボタンをクリックするとクライアントが実行され、Console ウィンドウにログが表示されます。

以上が、サーバで生成した乱数がクライアントに送信され Console に表示される流れとなります。

まとめ

Unity でネットワーク通信と考えると難しそうに考えがちですが、最小構成を見るととてもスッキリしていることがわかるかと思います。また SendData クラスを弄ることで、いろいろなデータを送受信できるようになります。今回はサーバからクライアントにデータを送信する流れを紹介しましたが、同様な方法でクライアントからサーバへもデータを送信できます。

TKS2では、UnityにおいてMirrorを用いたネットワーク通信を含むプロジェクトも可能ですので、もしお困りのときはぜひお声がけください。