- 投稿日:2021-03-04T22:15:19+09:00
MLAPIでOculus Quest2のマルチプレイ ③実機でテストするまで
レポジトリのリンク
シリーズ目次
①プロジェクトを実装するまで
②GCPにサーバー用ビルドをアップ・実行する
(今ここ→)③実機でテストするまでご注意
知見不足の箇所が多いかもしれません。すみません。
大変お手数ですがご指摘頂ければ幸いです。修正します。また、2021/03/03時点での記事です。
MLAPIは2020/12/4以降、数か月で改修されるそうなので必要なことが変わるかもしれません。
その時は加筆するつもりですが、あくまでご注意ください。MLAPIとは?
デニキさんという方が2021.2.24現在の全てをご説明なさっています。
とても分かりやすいので、ぜひご覧ください。
説明スライド
開発ブログ開発環境
Windows10
Unity(AndroidモジュールとLinuxモジュールを開発に使った)
Quest2, RiftS(2機あれば何でも大丈夫です)
対象読者と本記事の目的
ネットワークプレイでOculusの実機テストをしたい人
↓
こんな工夫を思いついたので、ちゃちですが聞いて頂きたいです
実装結果の動画も貼ります。テスト方法
OculusQuest2 → iPhoneでテザリング。楽天回線1年無料で無制限なのとても助かっております。
OculusRiftS → 光回線を繋げたPCに繋げるこうすることで、自宅にいながら異なるネットワークからアクセスできます。楽天回線がミソです。確か1年無料なのは2021年4月までの申し込みに限定されていました。以降は2980円/月だとか。
接続先のアドレスはシリーズ②の記事で取得したGCPのVMの外部IPアドレスで、ポート番号は7777で繋がりました。
テスト結果
シリーズ目次
- 投稿日:2021-03-04T17:33:40+09:00
[unityroom]アップロード後に画面が表示されない、Mac環境だけ重い時の対策
今回はUnity1Weekに参加した際に起きた問題を備忘録として残しておきたいと思います。
同じような問題につまづいている方の参考になれば幸いです!本文はこちら
https://tedenglish.site/unityroom-upload-trouble-solution/
- 投稿日:2021-03-04T14:34:33+09:00
MLAPIでOculus Quest2のマルチプレイ ①プロジェクトを実装するまで
レポジトリのリンク
シリーズ目次
(今ここ→)①プロジェクトを実装するまで
②GCPにサーバー用ビルドをアップ・実行する
③実機でテストするまでご注意
知見不足の箇所が多いかもしれません。すみません。
大変お手数ですがご指摘頂ければ幸いです。修正します。また、2021/03/03時点での記事です。
MLAPIは2020/12/4以降、数か月で改修されるそうなので必要なことが変わるかもしれません。
その時は加筆するつもりですが、あくまでご注意ください。MLAPIとは?
デニキさんという方が2021.2.24現在の全てをご説明なさっています。
とても分かりやすいので、ぜひご覧ください。
説明スライド
開発ブログ開発環境
Windows10
Unity(AndroidモジュールとLinuxモジュールを開発に使った)
Quest2, RiftSを用いたが、実機テストの時以外は関係がない
対象読者と本記事の目的
黒河さんのサンプルプロジェクト
黒河さんのサンプルプロジェクト解説動画
その他の記事やUnityの公式ドキュメント
などを見て、ある程度MLAPIについて把握したVRエンジニアの方々
↓
僕がVRでMLAPIを実装した際の工夫を把握できる本題
0. MLAPIマルチプレイのイメージ
まず、マルチプレイのイメージを共有した方が分かりやすくなると思うのでします。分かっていらっしゃる方は見逃して下さい。
自分は最初これすら知らずに実装したので苦しみました。なお、ヘッドレスサーバーに全QuestがClientとして接続するのを前提に図式を書きました。Relayサーバーを用いた場合などは図式が変わります。
①オンライン上の共通のSceneに接続するイメージではありません。
②各個人のSceneに通信で生じたデータが加えられるというイメージが正しいです。
AさんのSceneとBさんのSceneにあるGameObjectは違うものということです。
③そのため、Aさんのシーンの変化をBさんのシーンに反映させるには、サーバーを仲介するような操作が必要です。ServerRPCやNetworkedTransformはその操作の例です。フォントが黒いですね。まぁいいや。
④もちろんサーバーから対象のClientに向けて通信を行うこともあります。
新入りが接続した時に全員のシーンに新入りPlayerのプレハブを生成する場合などに使われるSpawnがそれにあたります。
具体的なスクリプトを見る場合は黒河さんのサンプルプロジェクトを覗くのをおすすめします。コメントや注意も日本語で残してあって分かりやすいです。なお、MLAPI改修後にはサンプルやドキュメントが整備されるそうなので、出来次第そちらを見るのもよいかと思います。
本記事にはネットになかった「OculusQuest2でMLAPIを用いたマルチプレイを実装する場合にどうするか」を検証した結果を書きます。基本黒河さんのスクリプトを改変させて頂きました。MITライセンスでした。
1. 接続先IPアドレス入力UIをVR向けにする
これは前提みたいなものですが、黒河さんのサンプルプロジェクトそのままのUIだとVRでIPアドレスを入力することが出来ません。RayなどVR用UIを用いる必要があります。ポート番号は7777で問題ありませんでした。
2. 新入りPlayer接続時は、全Clientに頭と両手(計3つ)のNetworkedObjectを生成させる
Networkで扱うGameObjectには全てNetworked Objectコンポーネントを付ける必要があります。加えて位置を同期する場合はNetworked Transform, アニメーションを同期する場合はNetworked Animationが必要です。
このNetworked Objectコンポーネントを頭を表す黄色い球とコントローラーのGameObjectに取り付けNetworkingManagerのリストに登録した一方で、OVRCameraRigはローカルでのみ扱うようにNetworked Objectコンポーネントを付けませんでした。その代わり、最初に頭のGameObjectをローカルのCenterEyeCameraの子になるようにしました。両手の場合はコントローラーの子にしました。
順を追って書きます。
1. 頭と両手を示すNetworkedObjectを作り、NetworkingManagerに設定した
※頭のGameObject
※ControllerのGameObject
2. Clientが接続してきたら3つのNetworkedオブジェクトをSpawnするようServerManagerを変えた
ServerManagerはサーバーの挙動が書かれたクラスです。
ServerManager.cs// ネットワーク同期するキャラクターオブジェクトを生成します private void SpawnCharacter(ulong clientId) { var netMgr = MLAPI.NetworkingManager.Singleton; for (int i = 0; i < netMgr.NetworkConfig.NetworkedPrefabs.Count; i++) { var networkedPrefab = netMgr.NetworkConfig.NetworkedPrefabs[i]; var gmo = GameObject.Instantiate(networkedPrefab.Prefab, Vector3.zero, Quaternion.identity); var netObject = gmo.GetComponent<NetworkedObject>(); // このNetworkオブジェクトをクライアントでもSpawnさせます netObject.SpawnWithOwnership(clientId); } Debug.Log("Spawn"); }3. 頭と両手のGameObjectがOVRCameraRigの中の適切な階層位置になるようSyncTransformをアタッチ
アタッチされたGameObjectがStart()時にparentTagのGameObjectの子要素となるスクリプトです。
これで頭をCenterEyeAnchorの子要素に、両手を各Controllerの子要素にしました。
OVRCameraRigはローカルにあるので、これで各自の頭や手の動きを同期できます。NetworkedBehaviourとはNetworkに接続しているとき、その状態などを扱いたい場合に使えるクラスです。これを継承することで、IsServer, IsOwnerなどの条件も使えるようになります。基本的にMonoBehaviourに書ける内容は書けました。
!IsServer → サーバーにOVRCameraRigを置かなかったので付けた条件です。
IsOwner → Aさんのものとして扱われるGameObjectはAさんをOwnerとしており、IsOwnerがTrueになります。位置同期の都合上この制限を足しました。
SyncTransform.csusing System.Collections; using System.Collections.Generic; using UnityEngine; using MLAPI; namespace TuneVisualizer { public class SyncTransform : NetworkedBehaviour { private Transform parent; public string parentTag; public Vector3 positionOffset; public void Start() { if (!IsServer & IsOwner) { transform.parent = GameObject.FindGameObjectWithTag(parentTag).transform; transform.position = transform.parent.position + positionOffset; } } } }ただし、このスクリプトだとローカル内では同じ位置にGameObjectが被って存在してしまいます。
気になる方は隠して下さい。[工事中]3. VRのみの話ではないが、Scene内で流れる曲のindexや再生時間を共有できるようにするための操作
NetworkedVarを扱いましたが上手く行かず、工事中です。
新MLAPIのサンプルに期待大。続き
apkを作ってもサーバー用のビルドをアップ・実行しない限り、マルチプレイは出来ません。
基本黒河さんのサンプルのような内容をLinux用にビルドするだけで機能は作れます。
ローカルで実行し、そこに繋げることも可能ですが、学習がてら次回の記事ではGCP(Google Cloud Platform)の仮想Linuxサーバーにアップ・実行します。シリーズ目次
(今ここ→)①プロジェクトを実装するまで
②GCPにサーバー用ビルドをアップ・実行する
③実機でテストするまでTilt Brush(OSS)をMLAPIでマルチプレイ化しようとして失敗したときの遺言メモ(自分用)
TiltBrushは3D絵具のMeshFilterを変えることで、3Dペイントを出力していた。
出来るかもしれないと思ったのは2つ。いずれも現状のMLAPIだと自分は詰まりそうで断念してしまった
- Spawnした後に、3D絵具のMeshFilterの変更をServerRPCで送る? https://www.reddit.com/r/Unity3D/comments/lkc1pd/photon_unity_networking_2_change_meshfilter_and/
- コントローラーの入力情報だけ共有する方法を模索
新MLAPIリリースに期待。
- 2020.12.4から数か月後と書いてあったので待つ
- それ以前にマルチプレイを実装しなければならないならphotonかmirrorを使う
- 投稿日:2021-03-04T07:41:24+09:00