Unity Photon2 自分以外のプレイヤーが消えてしまう問題についての解決法

はじめに

Unity勉強中です。
拙い説明ですがご了承ください。


問題発生時

Unityのミドルウェア?であるPhoton2を使ってマルチプレイ可能なゲームを実装中。
徐々に実装していく中で

  1. シーンAにてルーム情報の設定を行う(対戦形式など)

  2. シーンBに移動すると同時に自分のアバターを作成する

という部分でシーンBに後から入ったユーザー側で先に入ったユーザーが表示されない(オブジェクトがない)という事態が発生しました。

実装の問題点

シーンAにいるときに他のユーザーが自分のアバターを作成、その後シーンBに移動したことが問題でした
作成されたアバターはシーンAにいたらしく、シーン移動時に削除されてしまい、シーンBでは新しく作成されていないという状態だったみたいです。
全プレイヤーがシーンBに移動後、アバターの作成が必要した。

解決方法

  1. シーン移動前に他プレイヤーの処理を止める

  2. シーン移動を他のプレイヤーと同時に行う

の2つを実装しました。
順に説明します。

※他の方法(多分こっちが正攻法)
Unity Photon2を使用してシーン移動を同期させる簡単な方法|takataok|note


1.シーン移動前に他プレイヤーの処理を止める

その際に必要になる部分が

 PhotonNetwork.IsMessageQueueRunning = false;

という設定です。
内容としては

PhotonNetwork.IsMessageQueueRunning = falseの間は
他ユーザーの状態の変更を受け入れない

PhotonNetwork.IsMessageQueueRunning = trueになると
他ユーザーの状態の変更を一気に処理する

といった感じです。
シーン移動前にfalseに設定し、移動後にtrueにするという処理でシーン移動前に他プレイヤーの処理を止めるを実装できます。

2.シーン移動を他のプレイヤーと同時に行う

私はルームのプロパティの変更を利用しました。
ルームプロパティ変更時にルーム内のユーザーに対して特定の関数が実行されます。
つまり、「ルーム内のプロパティで”試合開始”を表すような変更があれば、各プレイヤーがシーンの変更を行う」を実装します。

シーンA側のスクリプト

    public void GameStart()
    {
        Hashtable Property = PhotonNetwork.CurrentRoom.CustomProperties;
        //nullの場合はエラーが発生する可能性があったので
        if (Property == null)
            return ;

        Property["Start"] = true;
        PhotonNetwork.CurrentRoom.SetCustomProperties(Property);
    }

    public override void OnRoomPropertiesUpdate(Hashtable Property)
    {
        if ((bool)Property["start"])
        {
            PhotonNetwork.IsMessageQueueRunning = false;
            //Photon自体の同期ズレが気になるのと、自分はアニメーションを入れているためInvokeを使用
            Invoke("/*シーンBへ移動する関数*/", 2.0f);
        }
    }

シーンB側のスクリプト

    void Awake()
    {
        PhotonNetwork.IsMessageQueueRunning = true;
    }

まとめ

  1. シーン移動前に他プレイヤーの処理を止める

  2. シーン移動を他のプレイヤーと同時に行う

の処理が必要でした。
他の実装としては

プレイヤープロパティに現在のシーンを保存しておき、
全プレイヤーがシーン移動したことを確認できたらアバター作成

もあるかなと思います。

他にもっと楽な方法があっても良いかと思いますが、自分は見つけられなかったです。知っている人がいれば教えてください・・・。


この記事が気に入ったらサポートをしてみませんか?