0 支持
(200 ポイント)
現在VRシューティングゲームをオンライン化しているのですが、

MonobitAutoLoginTemplateを使わない、プログラミング・チュートリアル<オフラインゲームのオンライン化>の方法を使ったやり方が分かりません。

方法をご存じの方がいれば教えてください。

よろしくお願いします。

回答 1

0 支持
(3.8k ポイント)

SteamVRの場合、CameraRigに含まれる Camera(head), Controller(left), Controller(right)の3種を同期させればそれで充分なのですが、MonobitView は親オブジェクトにのみ設定する必要があるので、多少の手間をかける必要があります。

同期するオブジェクトに同期用のコンポーネントを追加する
http://bit.ly/2TibT7L

この部分を参考に、

1. Camera(head) に MonobitView, MonobitTransformView を追加。
2. Camera(head)の MonobitView の ObservedComponentList に Camera(head) の MonobitTransformView を追加
3. Camera(head) の MonobitView を Controller(left) に移動
4. Controller(left) に MonobitTransformView を追加
5. Controller(left) に移動した MonoibitView の ObservedComponentList に Controller(left) の MonobitTransformView を追加
6. Controller(left) の MonobitView を Controller(right) に移動
7. Controller(right) に MonobitTransformView を追加
8. Controller(right) に移動した MonoibitView の ObservedComponentList に Controller(right) の MonobitTransformView を追加
9. Controller(right) の MonobitView を [CameraRig](親オブジェクト) に移動

で MonobitView を CameraRigに置いた状態で、Camera(head), Controller(left), Controller(right) の3オブジェクトの位置同期が取れると思います。

あとは CameraRig 内に含まれる Camera(head) > Camera コンポーネントについて、複数オブジェクトが存在した場合無効化する必要があるので
 

class CameraManager : MonobitEngine.MonoBehaviour {
    public void OnMonobitInstantiate(MonobitEngine.MonobitMessageInfo info)
    {
        // プレハブ生成されたときに、自分自身のオブジェクトでない場合、
        // 子オブジェクトのCameraを無効にする
        if( !info.monobitView.isMine ) {
            gameObject.GetComponentInChildlen<Camera>().enabled = false;
        }
}

を CameraRig のスクリプトとして組み込めば動くと思います。

(200 ポイント)
回答ありがとうございます。
上記のようにしてみたのですが、シーンにある[CameraRig]プレハブは消してしまってもいいのでしょうか?
[CameraRig]をResourcesフォルダに入れて、
http://www.monobitengine.com/doc/mun/
を参考にしてNetworkControl.csの34行目を”[CameraRig]”に変えてみたところ、生成された[CameraRig]のTransformのPositionとRotationがx=0,y=0,z=0になってしまいます。
どうすればよいでしょうか。
よろしくお願いします。
(3.8k ポイント)
> シーンにある[CameraRig]プレハブは消してしまってもいいのでしょうか?

はい。プレハブとして生成した後は消してください。

> NetworkControl.csの34行目を”[CameraRig]”に変えてみたところ、生成された[CameraRig]のTransformのPositionとRotationがx=0,y=0,z=0になってしまいます。

「そのまま」生成するオブジェクトをCameraRigに置き換えただけなのであれば、そういう設定になっているので、それで正常です。

                playerObject = MonobitNetwork.Instantiate(
                                "[CameraRig]",
                                Vector3.zero,
                                Quaternion.identity,
                                0);

上記の [CameraRig] に続くパラメータである

 Vector3.Zero =座標値(0, 0, 0)を示す
 Quaternion.Identity =回転量(0, 0, 0)を示す

ので、ここを適正な値に設定する必要があります。
例えば座標 ( 10, 20, 30 )、回転量(0, 90, 0)にするのであれば、


                playerObject = MonobitNetwork.Instantiate(
                                "[CameraRig]",
                                new Vector3(10, 20, 30),
                                Quaternion.Euler(0, 90, 0),
                                0);

などにしなければなりません。
(200 ポイント)
回答ありがとうございます。
上記のようにしたところ、[CameraRig]の出現位置は治ったのですが、以下のような不具合が出ました。
・相手のコントローラーに付けているオブジェクトがSceneでは見れるが、ゲーム画面(VRデバイス視点)からは見えない
・コントローラーに付けているオブジェクトがもう片方も一緒に動いてしまう
・相手のCameraの位置が同期しない
どうすればよいでしょうか。
よろしくお願いします。
(3.8k ポイント)
> ・相手のコントローラーに付けているオブジェクトがSceneでは見れるが、
> ゲーム画面(VRデバイス視点)からは見えない
> ・相手のCameraの位置が同期しない

この問題はネットワーク通信が原因かもしれませんし、同一シーンでの視点の違いで「見えない」のだとしたら、Camera の制御自体が全く異質なものになっているのかもしれません

http://support.monobitengine.com/index.php?qa=ask&follow=1314 内のコードの記述で Camera は OFF にされていますでしょうか。仮に Camera が「コンポーネント」として用意されているものではなく「オブジェクト」として用意されている場合、 Camera がOFF にならず、Camera位置の同期が行われないかもしれません。
現在 View として用いている Camera のオブジェクトが、CameraRig 内に存在しているのか、そこ以外に存在しているのかを確認した方が良いかと思います。

> ・コントローラーに付けているオブジェクトがもう片方も一緒に動いてしまう

この「コントローラーに付けているオブジェクト」がどういった形式で生成されているものなのでしょうか?仮に CameraRig 内に含まれている独立した同期オブジェクトなのであれば、http://support.monobitengine.com/index.php?qa=ask&follow=1314 の前半でも記述した通り MonobitTransformView をつけない限り同期しません。
また、デバイス依存で動作しているものであれば自身のクライアントの挙動に依存していますので、その依存を OFF にしなければなりません。

「自身が所有権を持つプレイヤー」だけを動かすようにする
http://www.monobitengine.com/doc/mun/contents/Tutorial/EnableIsMineControl.htm

に記載されている内容と同様、そのオブジェクトに含まれる Update() , FixedUpdate() メソッドなどを確認し、isMine で OFF にする必要があります。

この辺り、相応のテクニックを要すると思いますので、もし独力での解決が難しいようでしたら、差し障りのない範囲で GoogleDrive などに共有していただければ、何かしらのアドバイスはできそうな気がします。
(200 ポイント)
返信ありがとうございます。
申し訳ないのですが、知識不足で自分では限界がありました。
Cameraのほうは、コンポーネントではなく、オブジェクトとして用意されているかもしれません。
コンテンツ内容としてはシューティングゲームとなっています。プレイヤーの挙動を確認するため、敵は非アクティブにして発生しないようになっています。
下記のURLからギガファイル便に行けます。ダウンロードパスワードは0000です。
https://16.gigafile.nu/0122-fba3a8b903e0bcee591d831ca0aced79a
どうかよろしくお願いいたします。
(3.8k ポイント)
データ拝見しました。

> ・相手のコントローラーに付けているオブジェクトがSceneでは見れるが、
> ゲーム画面(VRデバイス視点)からは見えない

この部分については、そもそも Scene に存在している
・DefaultScene > [CameraRig] > Controller(right)
・DefaultScene > [CameraRig] > Controller(left)
の配置位置が「本来 VR の PlayArea としている範囲から遠くかけ離れたところ」にあるからだと思います。少なくともデフォルトの状態で VR Camera の近くになければ VRデバイス上から見えません。(ネットワーク同期以前の問題な気がします)

このあたり、Right Female Hand_Light の AnimatorController がないことも含め『もともとのデータから破壊されている』印象を受けるのですが、データ的に問題ありませんでしょうか?

> ・コントローラーに付けているオブジェクトがもう片方も一緒に動いてしまう
これについては、以下の手順で正常動作します。

1. いったん [Camera Rig] についている MonobitView を、[CameraRig] > Controller(right) > Right Female Hand_Light オブジェクト にドラッグ&ドロップして移動する。
2. Right Female Hand_Light オブジェクト に MonobitTransformView, MonobitAnimatorView を追加する
3. 上記で追加した MonobitTransformVIew/MonobitAnimatorView を、MonobitView の ObservedComponentList に追加する
4. Right Female Hand_Light オブジェクトについている MonobitView を、[Camera Rig]  にドラッグ&ドロップして移動し元に戻す。

で、うまくいきます。手順的に難しく、データ共有したいのですが、先に書いた通り [Camera Rig] のデータが破壊されている印象を受けるので、まずはそちらをご確認ください。正常であれば改めて以下の GoogleDrive から取得してください。
https://drive.google.com/drive/u/1/folders/15Uyvv_whpwhWKdSgWc8Kc3ar-nUKGAP1
(zip解凍パスワード : 0000)

> ・相手のCameraの位置が同期しない
Camera 位置は独立同期しますが、Camera に付随するデータについて isMine での切り分けができていない状態なので、 CameraManager.cs で以下のように not is mine なコンポーネントについて無効化すれば大丈夫だと思います。

public class CameraManager : MonobitEngine.MonoBehaviour {

    public void OnMonobitInstantiate(MonobitEngine.MonobitMessageInfo info)
    {
        // プレハブ生成されたときに、自分自身のオブジェクトでない場合、
        if (!info.monobitView.isMine)
        {
            // 子オブジェクトのCameraを無効にする
            gameObject.GetComponentInChildren<Camera>().enabled = false;

            // ヘッドマウントディスプレイのGUIも無効にする
            Transform gui = transform.Find("Camera/Score GUI");
            if (gui != null)
            {
                gui.gameObject.SetActive(false);
            }

            // プレイエリアも無効にする
            gameObject.GetComponent<MeshRenderer>().enabled = false;
            gameObject.GetComponent<Valve.VR.SteamVR_PlayArea>().enabled = false;

            // コントローラ操作&レンダリングを無効にする
            foreach(Transform child in gameObject.transform)
            {
                if (child.GetComponent<Valve.VR.SteamVR_Behaviour_Pose>() != null)
                {
                    child.GetComponent<Valve.VR.SteamVR_Behaviour_Pose>().enabled = false;
                    child.GetComponentInChildren<Valve.VR.SteamVR_RenderModel>().enabled = false;
                }
            }
        }
    }
(200 ポイント)
返信ありがとうございます。
ゲーム自体に問題がある可能性があったので、新しく作り直し処理を実装してみたところ、
おかげさまでプレイヤーの位置の同期がとれるようになりました。ありがとうございます。
そこから調整して、VIVEのコントローラーのトリガーを引くと弾丸がそれぞれで動くようにできたのですが、トラックパッドを長押しして打つ方の弾丸が、相手の画面に表示されません。
トリガーを使うときと方法はあまり変わらないはずなのですが、原因がわかりません。
一応ゲームのデータも上げておきますので、参照するのに使ってください。

ダウンロードパスワードは0000です。
https://39.gigafile.nu/0123-i3833d47b3c6ebe655d21bbcf40649b54

どうかよろしくお願いいたします。
(3.8k ポイント)
申し訳ありません。そもそも「トラックパッドを長押しして打つ方」がどこで組み込まれているのか分かりませんでした。

トリガーを使う方は [CameraRig] > Controller(right) > RightFemale Hand_Light > shooting で管理されており、こちらの方は同期は取れてはいるようです(RPCの送信間隔がデフォルトで1/20秒なので、通信を含めたフレーム単位での誤差はありますが)

 [CameraRig] > Controller(right) > RightFemale Hand_Light > shooting2 でもトリガーの処理が含まれていますが、こちらは shooting1 とは違い MUN を使った通信を行っていないようでしたので、shooting1 と同等の機能を組み込めば良いとは思います。

が、質問にありますトラックパッド操作の検知(SteamVR_Controller.ButtonMask.Touchpad)に関する記述が一切なされていないので、そもそもないのではないか、という懸念がありますが、いかがでしょうか?
(200 ポイント)
回答ありがとうございます。
トラックパッドの操作による球の発射のプログラムは、 [CameraRig] > Controller(right) > RightFemale Hand_Light > shooting2 でプログラムが組まれています。
shootingとは内容は似たようなプログラムだと思います。それにMUNを組み込んでも表示がされませんでした。
SteamVR_Controller.ButtonMask.Touchpadについては認識していなかったのですが、入れないと動かないのでしょうか?
よろしくお願いいたします
(3.8k ポイント)
先にデータ共有していただいたものですと、shooting2 で管理されている Deathblow.cs は以下のようになっています。

    private void Update()
    {
        // オブジェクト所有権を所持しなければ実行しない
        if (!m_MonobitView.isMine)
        {
            return;
        }

        float Pybullet = shootingScript.bulletCount;
        
        //スペースを押したら
        if (actionReload.GetStateDown(SteamVR_Input_Sources.RightHand))
        {
            StreamWriter DeathblowData = new StreamWriter(@"DeathblowData.txt", true, Encoding.GetEncoding("Shift_JIS"));
            DeathblowData.WriteLine(attention1);
            DeathblowData.Close();

            if (Pybullet >= 20)
            {
                sizeflag = true;
                // ball = Instantiate(target, transform.position, Quaternion.Euler(transform.parent.eulerAngles.x, transform.parent.eulerAngles.x, 0));
                ball = Instantiate(target, transform.position, transform.rotation);

                shootingScript.Deathblowattack(DeathblowATK);
                particleObgct = Instantiate(particle, transform.position, transform.rotation);
                shootingSource.Play();
                shootingSource.volume = shootingSourceVolume;

            }
        }

このうち、
>         if (actionReload.GetStateDown(SteamVR_Input_Sources.RightHand))
の条件式に当てはまる部分について、MUNを使った通信処理は一切なされておらず、同期するためには shooting1 と同じように組み込まなけれなりません。もちろん RPC のメソッドについては shooting1 に組み込んだ [MunRPC] コールバックメソッドとは別名にしておく必要がありますのでご注意ください。
...