はじめに
どうも、土鍋です。
今までVRでマルチプレイゲームを作る際、まともなチュートリアルが少なかったため、なかなかハードルが高かった。が、今年、Metaが公式の記事とBuilding Blocksにマルチプレイ用のものを追加した。
Photon FusionによるVRマルチプレイの実装はたまに見かけるので、今回はNetcode for Gameobjectsを使ってやってみた。
Meta公式記事
VRマルチプレイの準備
Metaのライブラリのインポート
いつものMetaのアセットをインポート

Netcode for Gameobjectsのインポート
Auto Matchmakingを使用するには以下のライブラリが必要だ。
Unity Netcode for Game Objects: com.unity.netcode.gameobjects
Unity Service Relay: com.unity.services.relay
Unity Service Lobby: com.unity.services.lobby
これらはAdd package by nameでインポートする。

Building Blocks
ネットワーク関連のBuilding Blocksが最近追加された。

Auto Matchmakingを追加する。今回はNetcode for Gameobjectsを使用する。

もろもろ追加してヒエラルキーは以下のような感じ。

プレイヤーの同期
ひとまず顔と手の同期しよう。
下のように適当なオブジェクトをシーンに置いて、NetworkObjectコンポーネントをつける。

Prefab化し、Default Network Prefabsに登録する。
これにより、Instantiateした際にもローカルだけでなくリモートでもInstantiateされる。

Network ManagerのPlayer Prefabに先程のPrefabを設定する。
これで、ゲーム再生時に自動的にマッチング開始され、プレイヤーがルームに入るとプレイヤーのPrefabも生成されるようになった。

頭と手の位置を同期する
以下のコードをPlayer Prefabにアタッチする。
public class NetworkPlayerSync : NetworkBehaviour { [SerializeField] private Transform head; [SerializeField] private Transform leftHand; [SerializeField] private Transform rightHand; private Transform _localPlayerHead; private Transform _localLeftHead; private Transform _localRightHead; // PlayerPrefabスポーン時に実行 public override void OnNetworkSpawn() { // ローカルのプレイヤーかどうか if (IsOwner) { LocalPlayerSync localPlayerSync = Camera.main.transform.root.GetComponent<LocalPlayerSync>(); _localPlayerHead = Camera.main.transform; _localLeftHead = localPlayerSync.leftHand; _localRightHead = localPlayerSync.rightHand; } } private void Update() { if(!IsOwner) return; // ローカルの顔の位置に合わせて、NetworkObjectの顔も動かす。 head.position = _localPlayerHead.position; leftHand.position = _localLeftHead.position; rightHand.position = _localRightHead.position; } }
これでマルチプレイでプレイヤーの頭と手の同期が可能になった。

ちなみにルーム周りの設定はデフォルトから変えていないので、ルーム入室機能などは別で作る必要があるだろうが、そこら辺はまたいつか別の記事で。
また、Metaのアバターを使用することもできる。それも別記事で書くかも?