UnityでPhoton PUN2を利用したオンラインゲームを開発していると、親オブジェクトは正常に同期されるのに、子オブジェクトだけが相手側の画面で動かないという問題が発生することがあります。これはPUN2の同期処理の仕組みと、PhotonViewの設定方法が関係しています。この記事では、親子構造を持つオブジェクトで子オブジェクトの動きを同期するために確認すべきポイントを解説します。
PUN2の同期はPhotonView単位で管理される
Photon PUN2では、すべてのオブジェクトが自動的に同期されるわけではありません。同期対象になるには、対象オブジェクトにPhotonViewコンポーネントを設定し、同期するデータを指定する必要があります。
例えば、親オブジェクトAにPhotonViewが設定されていても、子オブジェクトBにはPhotonViewが存在しない場合、親Aの位置や回転は同期されますが、子B独自の動きは相手側へ送信されません。
つまり「親が同期しているから子も同期する」という仕組みではなく、PhotonViewが付いている単位で同期処理が行われることを理解することが重要です。
子オブジェクトにもPhotonViewを設定する
子オブジェクトBを親オブジェクトAとは別に操作したい場合、子オブジェクトBにもPhotonViewを追加する必要があります。
設定例としては以下のようになります。
- 親オブジェクトAにPhotonViewを追加する
- 子オブジェクトBにもPhotonViewを追加する
- 子Bの位置や回転を同期するコンポーネントを設定する
- 所有権(Owner)が正しいか確認する
例えばキャラクター本体Aと武器Bを別々に動かすゲームの場合、キャラクターにはキャラクター用のPhotonView、武器には武器用のPhotonViewを設定することで、それぞれ独立した同期が可能になります。
PhotonTransformViewなどの同期コンポーネントを確認する
PhotonViewを追加しただけでは、位置や回転は同期されません。同期するデータを指定する必要があります。
よく利用される方法としてPhotonTransformViewがあります。PhotonViewの「Observed Components」にPhotonTransformViewを登録すると、位置・回転・速度などを同期できます。
例えば子オブジェクトBを回転させる場合、子BのPhotonViewにPhotonTransformViewを追加し、Observed Componentsへ登録する必要があります。
親AのPhotonViewだけにPhotonTransformViewを設定している状態では、子Bだけを回転させても、その情報はネットワークへ送信されません。
親子関係のあるオブジェクト同期で注意するポイント
UnityのTransformは親の影響を受けます。そのため、親子構造のオブジェクトを同期する場合は、どのTransformを同期するのかを明確にする必要があります。
例えば、親Aが移動し、子Bが親を基準に回転する場合、以下のような考え方になります。
- 親Aの移動は親AのPhotonViewで同期する
- 子Bの独自回転は子BのPhotonViewで同期する
- 単純に親について動くだけなら子Bの同期は不要
子オブジェクトが単なる装飾やモデルの一部であれば、親だけ同期すれば十分です。しかし、武器の向き変更、車のタイヤ回転、別プレイヤーが操作するパーツなどの場合は、子側にも同期設定が必要になります。
子オブジェクトの所有権(Ownership)を確認する
PUN2では、PhotonViewには所有者が存在します。基本的には所有者だけが、そのオブジェクトの状態をネットワークへ送信できます。
例えば、プレイヤー1が生成したオブジェクトAの子Bをプレイヤー2側で直接操作しても、所有権がプレイヤー1のままだと変更内容が同期されない場合があります。
この場合は、Transfer Ownershipを利用する、または操作権限を持つプレイヤーだけが変更する設計にする必要があります。
生成した子オブジェクトを同期する場合の注意点
PUN2でオンライン中に生成するオブジェクトは、PhotonNetwork.Instantiateを利用して生成することが基本です。
Unity標準のInstantiateで生成したオブジェクトは、ローカル上には存在しても、他のプレイヤーには自動的に共有されません。
例えば、ゲーム開始後に生成した武器オブジェクトを同期したい場合は、PhotonNetwork.Instantiateで生成し、そのオブジェクトにPhotonViewを設定しておく必要があります。
同期処理を確認するデバッグ方法
子オブジェクトが同期しない場合は、以下の順番で確認すると原因を特定しやすくなります。
- 子オブジェクトBにPhotonViewが存在するか確認する
- PhotonViewのObserved Componentsを確認する
- 同期したいTransformが正しく登録されているか確認する
- 子Bを操作しているプレイヤーがOwnerか確認する
- 生成方法がPhotonNetwork.Instantiateになっているか確認する
例えば、親キャラクターは動くが手に持った銃だけ動かない場合、銃側のPhotonView設定や所有権設定を確認すると原因が見つかることが多いです。
まとめ
Unity PUN2で親オブジェクトは同期するのに子オブジェクトが同期されない場合、原因の多くは子オブジェクト側に同期設定が存在しないことです。
PhotonViewは親から自動的に子へ引き継がれるものではないため、別々に操作したい子オブジェクトにはPhotonViewや同期コンポーネントを設定する必要があります。
また、所有権や生成方法もPUN2の同期では重要なポイントです。親子構造のオブジェクトをオンラインゲームで扱う場合は、どのオブジェクトを誰が操作し、どの情報を同期するのかを設計してから実装すると安定した動作になります。

コメント