UnityのMirrorアセットで最低限の構成(たぶん)でLAN内マルチユーザーを実現する話

さっそくですが、やりたいのはこういうことです。

f:id:at_you_key:20201104194718p:plain

LAN内マルチプレイで、ひとつのモデルの周りを、複数人で歩き回りたい。

そこで、LAN内でマルチプレイヤーする方法を探してみると、今は廃止されてしまった「UNET」という仕組みを使う情報が多いんですが、今やるなら、UNETと同じ感じで使えるという「Mirror」という無料アセットを使うのが良さそうです。

assetstore.unity.com

Mirrorの解説を探すと、インターネット越しの通信や、UNET経験者向けや、ある程度ゲーム制作を想定した説明が多くて、ちょっと理解しないと先に進むのが難しい印象でした。

この記事は、 「細かいことはいいから、とにかく手っ取り早く動かしたいんだ!」てな時のための、主に自分用のメモです。

手順

基本的な流れは、空のゲームオブジェクトを作り、Mirrorアセットに含まれるスクリプトをアタッチしていくだけです。

1. Mirrorアセットをインポートする

これがなくては始まりません、アセットストアでMirrorをゲットして、プロジェクトにインポートしておきましょう。 assetstore.unity.com

2. ゲームオブジェクトを作る

最低限必要なオブジェクトは2つだけです。空オブジェクトを作り、それぞれ名前をつけておきます。

  • NetworkManager
    • ネットワーク接続関係のスクリプトをアタッチする用です。
  • Player
    • プレイヤーのアバター用です。
    • アバターのモデルを入れておきましょう、ここではとりあえずCubeを使います。

ヒエラルキーがこの状態になっていればOKです。

f:id:at_you_key:20201104210003j:plain

3. 必要なスクリプトをアタッチする

  • [NetworkManager]に、次の2つをアタッチ
    • Assets/Mirror/Runtime/NetworkManager.cs
    • Assets/Mirror/Runtime/NetworkManagerHUD.cs(簡易的なGUIを表示する)

インスペクターはこうなります

f:id:at_you_key:20201104210054j:plain

  • [Player]には、次の2つをアタッチ
    • Assets/Mirror/Components/NetworkTransform.cs(Client Authにチェックを入れて、同期の向きをクライアント→サーバーしておきます。)
    • mirror-networking.com

    • PlayerMove.cs(テスト用に、とりあえずキーボードでPlayerを動かすスクリプトを用意しました、下をコピペで作ってください)

using Mirror;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove : NetworkBehaviour
{
    void Update()
    {
        if (isLocalPlayer) //ローカルプレイヤーだけ動かす
        {
            var h = Input.GetAxis("Horizontal"); //左右
            var v = Input.GetAxis("Vertical"); //前後
            
            this.transform.position += new Vector3(h * Time.deltaTime, 0, 0);
            this.transform.position += new Vector3(0, 0, v * Time.deltaTime);
            
            if (Input.GetKey(KeyCode.R)) //Rで回転
            {
                this.transform.Rotate(0, 0.5f, 0);
            }
        }
    }
}

すると、こうなっているはず。

f:id:at_you_key:20201104210129j:plain

4. 人数に応じてプレイヤーが自動生成されるようにする

いったんプレイヤーをプレハブにして

f:id:at_you_key:20201104210530j:plain

Network Manager のプレイヤープレハブ欄に登録します。

f:id:at_you_key:20201104212903j:plain

そうしたら、ヒエラルキー上のPlayerは削除しておきましょう。

これで、クライアント接続毎に、Playerアバターが自動生成されるようになりました。

5. 動かしてみよう

これで、最低限のマルチプレイヤーシーンができたはずです、ローカルで動作確認してみましょう。

複数立ち上げて並べてテストしたいので、[ファイル] > [ビルド設定] > [プレイヤー設定] > [解像度と表示] > [全画面モード]を[ウィンドウ化]にしておいてください。

ビルドして実行すると、簡易的なGUIが表示されます。

f:id:at_you_key:20201104210624p:plain

まずは、自分でサーバーを立てつつ、クライアントとしても接続する「Host」を選びます。

続けていくつか起動して、残りは「Client」にしましょう。

※Clientの接続先は、デフォルトでlocalhostになっています。ネットワーク越しに繋ぐ場合はIPアドレスやホスト名に書き換えればOKです。

そうすると、こんな感じです。

f:id:at_you_key:20201104210634p:plain

それぞれのウィンドウを選択して、キーボード操作すると、ちゃんとマルチプレイになっています!

今後の展望

冒頭の画像にある通り、最終的にはこれを複数台のOculus Questでやるのが目標です。

ToDo

  • ローカルプレイヤーの動きを、OVRCamerarigにリンクさせる
  • 両手の動きを同期させるために、子オブジェクトを同期するNetwork Transform Childを使う
  • GUI無しで接続したいので、Network Discoveryをうまく使う
    • Assets/Mirror/Components/Discovery/NetworkDiscovery.cs
  • Dissonanceアセットを使ってボイスチャットを追加

  • モデルをランタイム読み込みするためにTrilib2を使う

  • そして、それを記事にまとめる