Unityでオブジェクトの同期がうまくいかない?PUN2とSetActiveの違いを理解しよう

1. はじめに

Unityでネットワーク機能を利用して、リアルタイムで複数のプレイヤーが同じゲーム空間を共有することが一般的になってきました。その中で便利なのが**Photon Unity Networking 2(PUN2)**というライブラリです。しかし、ネットワーク同期の仕組みは複雑で、特に「オブジェクトの状態が他のプレイヤーに反映されない」という問題は初心者にとってつまずきやすいポイントです。

今回は、非アクティブのオブジェクトが同期されない場合の対処方法について説明します。この記事を通じて、SetActiveの違いやRPCの使い方を理解し、PUN2を活用できるようになりましょう。


2. 同期の問題

PUN2でプレイヤーの子オブジェクトを同期しているとき、ある子オブジェクトStatusTextは同期されるのに対し、別の子オブジェクトであるInfoPanelは同期されない状況が発生しました。

private async UniTaskVoid MonitorStatusAsync()
{
    while (true)
    {
        // 10秒間の経過後に infoPanel をアクティブにする
        if (Time.time - lastUpdateTime >= 10f)
        {
            infoPanel.SetActive(true);
            break;
        }
        await UniTask.Yield();
    }
}

このコードでは、10秒後にinfoPanelのSetActiveをtrueに設定していますが、この変更はローカルのみで反映され、他のプレイヤーには影響しません。つまり、自分の画面でしか反映されず、他のプレイヤーにはSetActive(true)の変更が伝わらないため、ネットワークでの同期が行われていない状態です。


3. 原因の解明

SetActiveの同期

PUN2では、SetActiveの状態変更が自動的に他のプレイヤーに反映されません。特に、非アクティブ(SetActive(false)状態のオブジェクトは、PUN2で監視されないため、他のクライアントに変更が伝わりません

PUN2でオブジェクトのアクティブ化を他のプレイヤーに伝えるには、**RPC(Remote Procedure Call)**を用いて明示的に変更を全クライアントに通知する必要があります。


4. 解決策:RPCでの同期

この問題を解決するために、以下のようにコードを修正していきます。

  1. PhotonViewの設定 まず、infoPanelがネットワーク上で同期されるように、PhotonViewコンポーネントをそのオブジェクトか親オブジェクトに追加します。

  2. RPCメソッドの追加 SetActiveの変更を全クライアントに伝えるために、[PunRPC]属性を使用してRPCメソッドを作成します。このメソッドでSetActive(true)の変更が全クライアントで行われるように設定します。

  3. MonitorInputAsyncメソッドの修正 MonitorInputAsync内で、10秒経過したタイミングでPhotonView.RPCを呼び出し、全クライアントにActivateConverseObjectメソッドを実行させます。

2で紹介するコード
[PunRPC]
public void ActivateInfoPanel()
{
    infoPanel.SetActive(true);
}
3で紹介するコード
private async UniTaskVoid MonitorStatusAsync()
{
    while (true)
    {
        // 10秒間の経過後に infoPanel をアクティブにする
        if (Time.time - lastUpdateTime >= 10f)
        {
            photonView.RPC("ActivateInfoPanel", RpcTarget.All);
            break;
        }
        await UniTask.Yield();
    }
}

このコードでは、RpcTarget.Allを指定することで、全クライアントでActivateInfoPanelが呼ばれ、他のプレイヤーの画面でもinfoPanelがアクティブ化されます。


5. なぜRPCを使うのか?

PUN2では、ローカルのみのSetActive変更は他のクライアントに反映されません。RPCを用いることで、ネットワーク越しに特定の処理を全クライアントで共有できるため、同期処理に欠かせません。これにより、全プレイヤーが一貫した画面状態を持つことができます。


6. 専門用語の解説

  • PUN2(Photon Unity Networking 2)
    Unityでマルチプレイヤーゲームを構築するためのライブラリ。プレイヤー間の同期やリモートプロシージャコール(RPC)などの機能を提供します。

  • SetActive
    Unityオブジェクトの表示・非表示を管理するメソッド。trueにすると表示され、falseにすると非表示になります。

  • RPC(Remote Procedure Call)
    リモートクライアントでメソッドを実行する仕組み。PUN2ではPhotonView.RPCで、他のクライアントにメソッド呼び出しを送信できます。

  • PhotonView
    PUN2でオブジェクトのネットワーク同期を行うために必須のコンポーネント。これを持つオブジェクトは、ネットワーク越しに状態変更やRPCの呼び出しを共有できます。


7. まとめ

PUN2を使った開発では、ローカルな状態変更が他プレイヤーに反映されないケースが多々あります。特にSetActiveのようなローカル処理を他のプレイヤーにも反映させるには、RPCで同期させるのが一般的な解決策です。今回紹介した方法を用いることで、PUN2での同期の仕組みをより深く理解し、トラブルを未然に防ぐことができるでしょう。


8. 今回の学びと生成AIの活用について

今回の内容を整理する際、学びを段階的にまとめ、記事の内容を生成AIを用いて添削し、わかりやすくしました。生成AIによる内容のチェックや表現の工夫を通して、読者により伝わりやすい内容を目指しました。今後の理解の助けになれば幸いです。

いいなと思ったら応援しよう!

この記事が参加している募集