This document is about: PUN 2
SWITCH TO

PUN Classic (v1)、PUN 2、Boltはメンテナンスモードとなっております。Unity2022についてはPUN 2でサポートいたしますが、新機能が追加されることはありません。お客様のPUNプロジェクトおよびBoltプロジェクトが停止することはなく、将来にわたってパフォーマンス性能が落ちることはありません。 今後の新しいプロジェクトについては、Photon FusionまたはQuantumへ切り替えていただくようよろしくお願いいたします。

オーナーシップとコントロール

PUNでは、ネットワーク化されたオブジェクトはPhotonViewコンポーネントを用いて確立されます。
それぞれの PhotonView には、作成者(インスタンス化)、オーナー、コントローラがあります。
このドキュメントでは、PhotonViewの制御と所有権に関する定義と概念について説明します。
また、さまざまな状況で予想される動作と、PhotonViewの所有権を明示的に変更する方法をリストアップします。

定義

アクター

アクターはルームのクライアントを表します。
各アクター/クライアントには、ルームに参加する際に新しいIDがインクリメンタルに割り当てられます。
最初にルームに参加したアクターはアクター1、2番目はアクター2となります。
アクターはメッセージのターゲット、PhotonViewsのオーナー/コントローラーとなり、マスタークライアントとして割り当てられます。
Creator、Owner、Controllerはすべて俳優を指しています。

PhotonView Creator

PhotonViewまたは'instantiator' (または'spawner' )の作成者は、PhotonNetwork.Instantiateを呼び出すアクターです。
このアクター番号は PhotonView.ViewID の一部であり、ViewID / PhotonNetwork.MAX_VIEW_IDS を用いて決定されます。
PhotonViewのViewIDは変更されないので、作成者のIDも変更されません。
ネットワーク化されたルームのオブジェクトの場合、作成者がいないので(null/0)、ネットワーク化されたオブジェクトはアクターによって作成されず、代わりにルームに関連付けられます。

PhotonView Owner

PhotonViewのオーナーは、PhotonViewのデフォルトコントローラーを示します。

ネットワーク化されたルームのオブジェクトの場合、オブジェクトのオーナーはルームであってアクターではないので、オーナー(null)は存在しません。
オーナーがいる場合、後者が有効であればコントローラにもなります。
それ以外の場合は、マスタークライアントが制御します。

PhotonView Controller

PhotonViewを制御するアクター(状態の権限を持つ)。

次の場合以外、オーナーは常にコントローラーです。

  • オーナーがnullの場合は。マスタークライアントがコントローラーになります。
  • オーナーがルームから切断された場合。
    PlayerTTLが0より大きい場合、ハード切断が発生する前にソフト切断としてアクターが退室する可能性があります。
    オーナーがソフト切断されている間は、マスタークライアントがコントローラになり、オーナーが再参加すると、オーナーが制御を再開します。

photonView.IsMineはphotonNetwork.LocalPlayerがこのphotonViewの現在のコントローラであるかどうかを示します。

ネットワーク化されたオブジェクト

ネットワーク化されたオブジェクトとは、PhotonViewコンポーネントやその子を持つGameObjectのことです。
ネットワーク化されたオブジェクトは、そのルートの PhotonViewコンポーネント、つまりトップレベル(ルート)のGameObjectにアタッチされた PhotonViewに表されます。

ネストされたネットワーク化オブジェクト

ネットワーク化オブジェクトの階層内に子の¥GameObject があり、そのうちの 1 つ以上に PhotonView がアタッチされている場合、それはネストしたネットワーク化オブジェクトとみなされます。
つまり、ネストされたネットワーク化オブジェクトは、別のネットワーク化オブジェクトの階層の一部のネットワークオブジェクトのことです。
通常、ネストされたネットワーク化オブジェクトを持つネットワーク化オブジェクトをインスタンス化するとき、すべての PhotonViewは同じインスタンスID (ルートの PhotonViewのViewID) を共有し、所有者やコントローラが異なるか、再ペアレント化されていない限り、同じライフタイムを持ちます。

ルームオブジェクト

ネットワーク化されたルームオブジェクトとは、アクターには属さないが、そのルームに属する「グローバルネットワーク化されたオブジェクト」です。
これはオーナー(null)もコントローラー(null)もなく、PhotonNetwork.Instantiate呼び出しの結果でもありません(ただし、PhotonNetwork.InstantiateSceneObjectの結果である可能性はあります)。

シーンオブジェクト

シーンオブジェクトは PhotonNetwork.InstantiateSceneObject を使ってランタイムインスタンス化されなかったルームオブジェクトです。
コンパイル時のUnityシーンの一部でした。

ソフト切断

ソフト切断とは、アクターがルームの中で無効になることです。
PlayerTTLが0と異なる場合と、以下の場合に発生します。

  • クライアントが切断される。
  • クライアントは、戻ってくるつもりで一時的にルームを出ます。

プレイヤーはPlayerTTLが期限切れになるまで非アクティブのままです。
PlayerTTL < 0またはPlayerTTL == int.MaxValueの場合、アクターは永遠にアクティブのままでいられます。

予期せぬソフト切断から回復するには、PhotonNetwork.ReconnectAndRejoin()を使用するか、PhotonNetwork.RejoinRoomを使用して同じルームに再接続します。
どちらの場合も、クライアントは同じ UserId を保持する必要があり、アクターは再入室時に同じアクター番号と以前のすべてのアクターのプロパティを再取得します。

ハード切断

ハード切断とは、あるアクターがルームのアクターリストから完全に削除された場合のことです。
PhotonNetwork.CurrentRoom.PlayerTtl == 0の場合。

  • クライアントがPhotonサーバーから切断。
  • クライアントがルームから退室。

PhotonNetwork.CurrentRoom.PlayerTtl != 0の場合:

  • クライアントが完全にルームから退室
  • 非アクティブなアクターのPlayerTTLはが期限切れになる

自動コントロール移行

ソフト切断時

ハード切断したローカルクライアント上で:

  • ルームがroomOptions.CleanupCacheOnLeave == trueで作成された場合:

    • ランタイムにインスタンス化されたネットワークオブジェクトからシーンオブジェクトの親を解除します(破壊を防ぐため)。

    • このアクターによって作成されなかったネスティングされたネットワークエンティティは、破棄する前にオブジェクトの親ではなくなります。

    • 切断するアクターによって作成された、実行時にインスタンス化されたネットワークオブジェクトはすべて破棄されます。

    • その他のネットワーク接続されたオブジェクトはデフォルトにリセットされます。

  • If the room was created with roomOptions.CleanupCacheOnLeave == false:

    • 何も変わりません。手作業でクリーンアップする必要があります。

リモートクライアントの場合(ある場合)。

  • ソフト切断したアクターが以前に所有していたPhotonViewの所有権は変更されません。
  • マスタークライアントは、ソフト切断したアクターが所有するPhotonViewsのコントローラになります。

ハード切断時

ハードディスコネクトされたローカルクライアント上:

  • ルームが roomOptions.CleanupCacheOnLeave == true で作成された場合:

    • 切断するアクターのインスタンス化されたネットワークシーンオブジェクトの親を解除する(破壊を防ぐために)
    • 切断されたアクターによって作成された、ランタイムにインスタンス化されたネットワークオブジェクトは破棄されます。
    • キャッシュされたインスタンス化イベントやバッファされたRPCは中継サーバから削除されます。
    • シーンオブジェクトがリセットされます。
  • ルームが roomOptions.CleanupCacheOnLeave == false で作成された場合:

    • 何も変わりません。手作業でクリーンアップする必要があります。

リモートクライアント上(ある場合):

  • 切断するアクターのネスティングされたネットワークシーンオブジェクトの親を解除する(破壊を防ぐために)
  • 切断されたアクターによって作成された、ランタイムにインスタンス化されたネットワークオブジェクトは破棄されます。
  • ハード切断されたアクターが以前に所有していた残りのPhotonViewの所有権をリセットします(所有者がnullになります)。
    それらは親のないネットワークオブジェクトになります。
  • オーナーがnullの場合、マスタークライアントが常にコントローラであるため、マスタークライアントはこれらの親のないPhotonViewのコントローラになります。

再入室の場合

Player.HasRejoined == true

クライアントが空室ではないルームに再入室した場合。

  • 同じアクターが所有するネットワーク化されたオブジェクトの制御を再取得します。
  • [任意] マスタークライアントは、owner != creatorのネットワークオブジェクトに対してOwnershipUpdate を再送します。

サーバー上にあるが空のルームにクライアントが再参加した場合(EmptyRoomTTLの有効期限がまだ切れていない):

  • 同じアクターが所有するネットワーク化されたオブジェクトの制御を再取得します。
  • マスタークライアントなので、他のすべてのネットワーク上のオブジェクトも制御します。

クライアントがルームを「復活」させて再入室した場合(外部ソースから状態を再読み込み):

  • 同じアクターが所有するネットワーク化されたオブジェクトの制御を再取得します。
  • マスタークライアントなので、他のすべてのネットワーク上のオブジェクトも制御します。

新規入室の場合

Player.HasRejoined == false

クライアントが空室ではないルームに再入室した場合。

  • 通常通り

サーバー上にあるが空のルームにクライアントが再参加した場合(EmptyRoomTTLの有効期限がまだ切れていない):

  • 同じアクターが所有するネットワーク化されたオブジェクトの制御を再取得します。
  • マスタークライアントなので、他のすべてのネットワーク上のオブジェクトも制御します。

クライアントがルームを「復活」させて再入室した場合(外部ソースから状態を再読み込み):

  • 同じアクターが所有するネットワーク化されたオブジェクトの制御を再取得します。
  • マスタークライアントなので、他のすべてのネットワーク上のオブジェクトも制御します。

マスタークライアント変更の場合

新しいマスターが以下のコントローラーになります:

  • "孤児" ネットワーク化されたオブジェクト:オーナーのいないネットワーク化されたオブジェクト。
  • 所有者が非アクティブなネットワーク化されたオブジェクト。

注: 前のマスターがソフト切断した場合、所有権を主張したネットワークルームオブジェクトの所有権を保持します。

明示的なオーナーシップの移転

ネットワークオブジェクトの所有者を明示的に変更するには、それぞれのルートPhotonViewを使用します。
デフォルトでは、ネットワーク化されたオブジェクトの所有者は固定されていますが、これを変更することで、直接またはリクエストで所有者を変更することができます。
所有権の変更は通常、コントローラ(制御者)の変更を意味し、新しい所有者が非アクティブでない限り、その所有者がネットワークオブジェクトを制御します。

所有権移転オプション

PhotonViewの所有権移転の動作は、PhotonView.OwnershipTransferで設定されたOwnershipOption で定義されます。
PhotonView.OwnershipTransfer はネットワーク上では同期されないので、PhotonViewがインスタンス化されたら変更しないでください。
所有権移転オプションにはFixed, Request, Takeoverの3つのタイプがあります。
それぞれについて個別に説明しましょう。

Fixed

所有権は固定されています。
ルームオブジェクトの場合、所有者はありませんが、マスタークライアントがコントローラーとなります。
プレイヤーオブジェクトの場合は、作成者が常に所有者となります。
これがデフォルト値です。

Request

OwnershipTransferオプションが Requestに設定されている場合、アクターは現在の所有者(またはコントローラー)に PhotonViewの所有権を要求することができます。

これは2つのステップで行われます。最初にアクターがPhotonViewの所有者にリクエストを送信し、後者がそれを受け入れれば所有権の移転がオーナーによって明示的に行われ、リクエストしたアクターが新しい所有者になります。
リクエストはPhotonView.RequestOwnership()を経由して行われます。

これは現在の所有者に対してIPunOwnershipCallbacks.OnOwnershipRequest(PhotonView targetView, Player requestingPlayer)コールバックを発生させ、開発者は実際の所有権の変更を行うためにtargetView.TransferOwnership(requestingPlayer)を呼び出す必要があります。これにより、開発者はコードの中でそのリクエストが受け入れられるかどうかを判断することができます。

ネットワークオブジェクトの現在の所有者か現在のコントローラーのみが所有権の移転要求を受け付けることができます。

Takeover

アクターはTakeoverOwnershipTransferオプションとして指定したPhotonViewの所有権を変更することができます。

このオプションは、現在の所有者の同意なしにPhotonViewの所有権を直接主張したり、PhotonViewを他の誰かに帰属させたりすることを目的としています。
この場合、所有権を引き継ぐにはPhotonView.TransferOwnership(Player newOwner)を呼び出すだけです。
アクターXはTakeoverに設定されたPhotonViewの所有者をアクターYからアクターZに変更することができます。

OwnershipTransferオプションにTakeoverを指定したPhotonViewに対してPhotonView.RequestOwnership()をコールすると、コールバック処理を行わなくても自動的にリクエストが受け付けられます(他の誰かが引き継がない限り)。
しかし、Takeoverのオーナーシップオプションの場合は、PhotonView.TransferOwnership(Player newOwner)を直接呼び出すことを推奨します。

所有権の放棄

PhotonViewの所有権が固定されていて変更されない限り、どのアクターも自分のPhotonViewの所有権を他のアクティブなアクターに譲渡することができます。
これは PhotonView.TransferOwnership(Player newOwner)を使って行います。

PhotonView コールバック

所有権変更コールバック

PhotonViewの所有者が変わるたびに、それを実装したクラスと同じ PhotonView に登録されているクラスでIonPhotonViewOwnerChange.OnOwnerChange(Player newOwner, Player previousOwner)が発生します。

IOnPhotonViewOwnerChangeインターフェースを実装しているクラスは、PhotonView.AddCallbackTargetで登録し、PhotonView.RemoveCallbackTargetで登録を解除します。

明示的な所有権移転コールバック

同じIPunOwnershipCallbacksインターフェースに2つの所有権変更コールバックがあります。

  • 誰かがTargetViewに所有権を要求した時のOnOwnershipRequest(PhotonView targetView, Player requestingPlayer)
  • TargetViewの所有者が変わる際のOnOwnershipTransfered(PhotonView targetView, Player previousOwner)

IPunOwnershipCallbacksインターフェースを実装するクラスは、PhotonNetwork.AddCallbackTargetで登録し、PhotonNetwork.RemoveCallbackTargetで登録を解除する必要があります。

制御変更コールバック

PhotonViewのコントローラーが変更されるたびに、IonPhotonViewControllerChange.OnControllerChange(Player newController, Player newController)がそれを実装したクラスと同じPhotonViewに登録されているクラスに対して発行されます。

IonPhotonViewControllerChangeインターフェースを実装したクラスはPhotonView.AddCallbackTargetで登録し、PhotonView.RemoveCallbackTargetで登録を解除する必要があります。

ネットワーク破棄コールバック

ネットワーク接続されたオブジェクトが破壊されそうになったときに通知を希望する場合もあります。
このために使用できるコールバックがあり、同じネットワークオブジェクトのすべての PhotonView (メイン/ルートのPhotonViewとそれにネストされているものがあればすべて)に対しても発生します。

PhotonNetwork.Destroyが呼ばれるたびに、ネットワークの破壊が終わる直前にIonPhotonViewPreNetDestroy.OnPreNetDestroy(PhotonView rootView)が呼び出され、それを実装したクラスと同じPhotonViewに登録されているクラスに対して IonPhotonViewPreNetDestroy.OnPreNetDestroy(PhotonView rootView)が発生します。

IOnPhotonViewPreNetDestroyインターフェースを実装するクラスは PhotonView.AddCallbackTargetで登録し、PhotonView.RemoveCallbackTarget で登録を解除する必要があります。

Back to top