ネットワークオブジェクト
概要
NetworkObject コンポーネントは GameObject にネットワーク ID を割り当てて、ネットワーク上で共有できるようにします。全てのプレイヤーに表示され、シーンの一部となる GameObject は、 NetworkObject スクリプトを持つ必要があります。
Fusion では、NetworkObject にカスタムのネットワーク動作を作成するためのクラスが2つ用意されています。
- シミュレーション関連のビヘイビアを作成する
SimulationBehaviourと、 NetworkBehaviourは[Networked]状態を維持、または追跡する動作です
NetworkObject
GameObject のルートノードにある NetworkObjectスクリプト一つで、階層全体をコントロールすることができます。実行時に NetworkObject は、その階層にある全ての SimulationBehaviour と NetworkBehaviour を探します。
必要であれば、NetworkObjectをネストすることができます。この場合、NetworkObject はネストした子オブジェクトを検索せず、子オブジェクトの NetworkObject にその下の SimulationBehaviour と NetworkBehaviour をすべて追跡させることができます。典型的な使用例としては、運転手がシャシーの方向(移動)をコントロールし、射撃者がタレット(射撃)をコントロールする2人乗り戦車です。
プレハブ / オブジェクトテーブル
Fusion で Prefab パラメータが意味を持つようにするには(そして全てのクライアントが正確にどのプレハブであるかに同意するようにするには)、プレハブ自体が Fusion に登録されている必要があります。通常であれば、Fusionツールセットが自動的にプレハブを検出し登録しますが、手動で検出することも可能です。その場合は、NetworkProjectConfigを選択し、Unity InspectorでRebuild Object Tableを押します。
インスタンス化 / スポーン
NetworkObject プレハブのインスタンス化は、2つのステップを必要とします。
- 編集時: クライアントが
NetworkProjectConfigアセットで、NetworkObjectプレハブの ID を一致させる必要があることを確認します。これは、NetworkProjectConfigアセットでRebuild Object Tableを実行することで行われます。 - 実行時:
NetworkRunnerのSpawn()を、NetworkObjectプレハブをパラメータとして呼び出します。
__ 重要:__ Unity の一般的な Instantiate() メソッドを呼び出すと、壊れたローカルインスタンスが作成されます!
破壊 / デスポーン
NetworkObject を破棄するには、 Runner.Despawn() を呼び出し、パラメータとしてオブジェクトを渡してください。これはオブジェクトだけでなく、ネストした全てのオブジェクトを破壊します。トップオブジェクトだけをデスポーンするには、ネストしたオブジェクトをまず手動でデペアレンティングする必要があります。
NetworkObject の検索
ネットワークオブジェクトのインスタンスを参照する NetworkId を渡すことで、 NetworkRunner.TryFindObject() を使って NetworkObject を見つけることができます。
NetworkId と NetworkObject は [Networked] 属性でネットワーク化できますが、NetworkObject をネットワーク化すると Game State に NetworkId を追加するだけです(実際の NetworkObject のデータはバッファにコピーされず、その参照のみが行われます)。
Networked] NetworkObject にアクセスするときは、あらかじめ NetworkRunner.TryFindObject() が実行されますので、ID をネットワークして手動で行うか、オブジェクトそのものをネットワークするかは開発者の選択となります。
State Authority
State Authorityは、[Networked]プロパティの正しい値を変更し決定する権利を持つ人を示します。
概念自体はFusionの全てのトポロジーで同じですが、機能的な違いがあります。
ServerModeとHostMode
ServerModeとHostModeでは、サーバ/ホスト上のシミュレーションは単一状態権限です。そのため、Object.HasStateAuthorityを使ったif文で、そこでしか実行されないはずのコードパスをカプセル化することが可能です。Object.HasStateAuthority は、サーバー/ホスト上でしか true を返しません。
Server/Clientモードでは、この値は常に PlayerRef.None となります。Server/Hostピアは常にState Authorityとして機能するからです。
SharedMode
SharedModeでは、プレイヤー間で状態権限が_共有_されます。各プレイヤーはシミュレーション内のある数のオブジェクトに対して状態権限を持つことができます。したがって、Object.HasStateAuthorityは、その権限を持つプレイヤーに対してtrueを返します。Photon Shared ServerはNetworkObjectsのState Authorityを_管理_しますが、それらのオブジェクトに対するState Authorityは持ちません。
State Authorityは、NetworkObjectの状態(Networked Properties)の最終的な権限がどのPlayerRefのピアにあるかを示し、そのNetworked Propertyの値はTick Snapshotsとして他のクライアントへレプリケートされます。
注意: StateAuthority プロパティは Shared Mode にのみ適用されます。
NetworkObject の State Authority は SharedMode で変更することができますが、与えられたオブジェクトに対してそれを持つプレイヤーは常に一人だけです。複数のプレイヤーが同じオブジェクトの状態権限を持つことはできません!
DestroyWhenStateAuthorityLeaves: このNetworkObjectがStateAuthorityを持つプレイヤーによってゲームから離れた時に自動的にデスポーンされるかどうかを指定します。AllowStateAuthorityOverride: 他のプレイヤーが既に状態権限を持っている場合に、そのプレイヤーが状態権限を取得できるかどうかを示します。このプロパティはスポーン後に変更することができないため、スポーン前に設定する必要があります。ほとんどの使用例では、プレハブやシーンオブジェクトのAllowStateAuthorityOverrideを有効のままにしておいてください。ReleaseStateAuthority(): 現在の状態権限者はオブジェクトの制御を解放します。RequestStateAuthority(): クライアントから呼び出され、PlayerRefをNetworkObjectのState Authorityとして割り当てることができます。Photon Shared Serverは以下の場合にのみリクエストを許可します。- オブジェクトは
AllowStateAuthorityOverrideを有効にしている。 - Object に現在の State Authority がない。これは、State Authorityがゲームセッションから離脱したか、または以前にオブジェクトに対して
ReleaseStateAuthority()を呼び出してコントロールを放棄したためである可能性があります。
- オブジェクトは
StateAuthorityChanged(): オブジェクトに対する状態の権限が変更されたときにIStateAuthorityChangedインターフェースの実装から呼び出されるコールバック。
入力権限(InputAuthority)
InputAuthority プロパティは、この NetworkObject の FixedUpdateNetwork において GetInput() が呼ばれたときに、どの PlayerRef の入力データ (INetworkInput) が返されるかを表します。プレイヤー入力は、Input Authority を持つクライアントと State Authority のみが利用できます。その他のクライアント(プロキシ)は、GetInput()が呼び出されるとfalseを返します。
InputAuthorityとFusionの INetworkInput 処理は、主に ServerMode と HostMode のために用意されています。しかし、SharedModeでは、ユーザーの入力はすぐにState Authorityによって消費されるので、INetworkStruct入力システムは必須ではありません。将来的に ServerMode や HostMode に切り替えたときに役立つように、SharedMode では Fusion input system を使用することが望ましいかもしれませんし、後々のリファクタリングを避けることもできます。
HasInputAuthority:Runner.LocalPlayer == Object.InputAuthorityの場合、trueを返します。スクリプトで、NetworkRunner.LocalPlayerがNetworkObjectのState Authorityを持っているかどうかをテストするために使用します。AssignInputAuthority(): このメソッドに渡されたPlayerRefにState Authorityを割り当てます。これはオブジェクトのState Authorityによってのみ変更することができます。RemoveInputAuthority(): State AuthorityをPlayerRef.Noneに設定することにより、NetworkObjectからState Authorityを削除します。これは、オブジェクトのState Authorityによってのみ変更することができます。