Hlapiネットワークのスポ―ニングのチュートリアル
ネットワーク生成と高レベルネットワークAPIの連動。
はじめに
ネットワークのスポーンとは、Unityの Instantiate
メソッドをネットワーク上で実現したものです。 GameObject
とその MonoBehaviour
コンポーネントを単一デバイス上でスポーンするのではなく、事前に登録されたNetworkedUnityObjectをスポーンし、関連情報を含むネットワークメッセージをピアに送信して、同一のオブジェクトをスポーンできるようにします。
NetworkedUnityObject
スクリプトには、新しくスポーンされたオブジェクトをHlapiSessionに登録し、オブジェクト上のすべてのNetworkedDataHandlerを他のデバイス上の同等のものと同期を行うための配管が含まれています。
プレハブマニフェストのセットアップ
ネットワークでスポーンされるすべてのオブジェクトに対して、
NetworkedUnityObject
とAuthBehaviourコンポーネントをアタッチします(通常、オブジェクトの動作を定義するために、NetworkedBehaviourも必要になります)。Asserts(アサート)**> Create(作成)> Networking(ネットワーク)> Spawnning(スポーン)> PrefabManifest(プレハブマニフェスト) の順に移動して、
PrefabManifest
アセットを作成します。ネットワークでスポーンされるすべてのオブジェクトのプレハブを
PrefabManifest
に追加します (要素数を変更するとリストは拡大または縮小します)。最後に、NetworkSceneSpawnManifestコンポーネントをシーンに追加します。
ネットワークスポーンオブジェクト
マニフェストが設定されている場合、オブジェクトのネットワークスポーンのAPIコールは1回のみで済みます。
using Niantic.ARDK.AR.Networking.ARNetworkingEventArgs; using Niantic.ARDK.Networking.HLAPI.Object.Unity; // Reference set in the Inspector public NetworkedUnityObject _objectToNetworkSpawn; void SpawnObjectForAllPeers() { NetworkedUnityObject spawnedInstance = _objectToNetworkSpawn.NetworkSpawn(); }
ネットワーク破壊オブジェクト
NetworkedUnityObject
を参照することで、ネットワーク破壊は、次のように簡単にできます。
void DestroyNetworkedUnityObject(NetworkedUnityObject objectToDestroy) { objectToDestroy.NetworkDestroy(); }
各 NetworkedUnityObject
の有効なデストラクタは、エディタを通じてプレハブに設定できます。
ARDKは、Unityシーンのクローズ時や UnityEngine.Destroy
で破壊されたオブジェクトに対して、ネットワーク破壊メッセージの伝播を試みます。ピアがオブジェクトの有効なデストラクタでない場合、ARDKは UnityEngine.Destroy
を防ぐことはできませんが、メッセージは伝搬されません。
さらに、 MultipeerNetworking
のセッションはすでに破棄されている可能性があるため、シーンのアンロード時にメッセージが伝搬される保証はありません。有効なデストラクタが破棄されたときにクリーンアップされるべき NetworkedUnityObjects
(つまり、ピアが離脱した後にピアのアバターが宙に浮かないようにする)については、 DestroyIfDestructorLeaves
オプションを有効にして、各デバイスでクリーンアップをローカルに処理します。複数のピアがオブジェクトを破壊できる場合は、最初のピアが離脱すると、ローカルクリーンアップが行われます。
ネットワークスポーンの実装の詳細
オブジェクトが NetworkSpawned
の場合、 NetworkedUnityObjects
、NetworkGroups
、 NetworkBehaviours
には何が起きているでしょうか。
一般的なGameObjectやPrefabには、アタッチするための
NetworkedUnityObject
コンポーネントが付属しており、NetworkedUnityObject
となり、AuthBehaviour
コンポーネントが自動的に追加されます。この時点でそれ以外のNetworkedBehaviours
を作成し、NetworkedUnityObject
に追加することができます。エディタスクリプトNetworkedUnityObjectEditor
によって、RawId
やPrefabId
がNetworkedUnityObject
に自動的に割り当てられ、Behaviours
リストが追加されます。作成された
NetworkedUnityObject
はPrefabManifest
アセットに登録され、NetworkSceneSpawnManifest
コンポーネントを通じてシーンのロード時に読み込まれます。この手順により、ビルドが同一のセッション内のすべてのピアに、スポーン可能なNetworkedUnityObjects
が共有されます。PrefabManifest
を更新する場合は、すべてのクライアントを再構築することが重要です。そうしないと、旧クライアントが認識していないNetworkedUnityObject
が生成される可能性があります。クライアントが
NetworkedUnityObject
に対してNetworkSpawn
を呼び出すと、NetworkSpawn
を呼び出したクライアントのオブジェクトが直ちにインスタンス化され、ランダムに生成されたRawId
が新しいオブジェクトに割り当てられます。その後、クライアントは全てのスポーン情報(transform、PrefabId、RawIdなど)をシリアライズし、セッション内の他のクライアントにその情報を送信します。スポーン情報を受け取ったクライアントは、読み込んだ
PrefabManifest
の中から要求されたPrefabId
を検出し、検出すると対応するNetworkedUnityObject
をインスタンス化します。
NetworkedUnityObject
のインスタンス化後、NetworkSpawnerはNetworkedUnityObject.Initialize()
を呼び出し、ランダムに生成されたRawId
(すべてのクライアントに対して複製されている)を使用して新しいNetworkGroup
を作成します。このステップにより、作成され、NetworkedUnityObject
にアタッチされたNetworkedDataHandlers
はすべて、正しいNetworkGroup
にデータが自動的に送信されます。続いて、
NetworkedUnityObject.Initialize()
は、アタッチされた各NetworkedBehaviour.Initialize()
を呼び出し、アタッチされたすべてのNetworkedBehaviours
の初期化を順番に(オーバーライドされたNetworkedBehaviour.SetupSession
で定義)並べ替え、SetupSession
をそれぞれ順番に実行します。この時点で、SetupSession
で作成されたNetworkedDataHandlers
(NetworkedFields
、MessageStreamReplicators
など)がすべて作成され、Hlapiシステムに登録されるため、データの送受信を開始することができます。