Hlapiに関するよくある質問
高レベルネットワークAPIに関するよくある質問。
ネットワーク化されたUnityオブジェクト
独自のNetworkedBehaviourはどのように作成できますか?
MonoBehaviourを拡張するとスクリプトによってUnityのイベントやシステムと統合できるように、NetworkedBehaviourを拡張することでHlapiと統合できるようになります。(エディタ経由で)NetworkedUnityObjectにアタッチされ、そのオブジェクトの Behaviours
リストに登録された NetworkedBehaviour
はそれぞれ、そのオブジェクトがネットワークでスポーンされるたびに自動的に初期化されます。これにより、指定の Group
にNetworkedDataHandlerを登録することができます。オブジェクトの寿命やタグ付けはHlapiで処理されるため、気にする必要はありません。
たとえば、次のスクリプトでは、Transform
や Color
の複製を設定する NetworkedBehaviour
を実装します。スポーンされた NetworkedUnityObject
にはそれぞれ固有の NetworkGroup
が割り当てられるため、これらのNetworkedDataHandlerに書き込むことで、他のデバイス上の相当するオブジェクトにのみ影響を与えます。
using System;
using Niantic.ARDK.Networking;
using Niantic.ARDK.Networking.HLAPI.Data;
using Niantic.ARDK.Networking.HLAPI.Object;
using Niantic.ARDK.Networking.HLAPI.Object.Unity;
using Niantic.ARDK.Utilities;
using UnityEngine;
[RequireComponent(typeof(AuthBehaviour))]
public sealed class SampleNetworkedBehaviour :
NetworkedBehaviour
{
[SerializeField]
private TransformPiece _replicatedPieces = TransformPiece.All;
// Reference to the material on the GameObject
[SerializeField]
private Material _material;
private UnreliableBroadcastTransformPacker _transformPacker;
private NetworkedField<Color> _networkedColorField;
// Define an initializer that will be run as soon as the NetworkedUnityObject
// has been spawned
protected override void SetupSession(out Action initializer, out int order)
{
initializer = () =>
{
NetworkedDataDescriptor authToObserverDescriptor =
Owner.Auth.AuthorityToObserverDescriptor(TransportType.UnreliableUnordered);
// Create an UnreliableBroadcastTransformPacker that
// replicates Position, Rotation, and Scale
_transformPacker = new UnreliableBroadcastTransformPacker
(
"NetTransform",
gameObject.transform,
authToObserverDescriptor,
_replicatedPieces,
Owner.Group
);
_networkedColorField = new NetworkedField<Color>
(
"color",
authToObserverDescriptor,
Owner.Group
);
_networkedColorField.ValueChangedIfReceiver += OnColorFieldChanged;
};
order = 0;
}
// When this is called by the peer that has the role Authority, all
// Observing peers will receive a ValueChangedIfReceiver event
private void UpdateColorForAllPeers(Color newColor)
{
_networkedColorField.Value = newColor;
}
private void OnColorFieldChanged(NetworkedFieldValueChangedArgs<Color> args)
{
Optional<Color> optionalValue = args.Value;
if (!args.Value.HasValue)
{
return;
}
_material.color = args.Value.Value;
}
private void OnDestroy()
{
_transformPacker.Unregister();
_networkedColorField.Unregister();
}
}
NetworkedDataDescriptorは何に使用しますか?
NetworkedDataDescriptor
は、認証済みの送受信者や、ネットワークプロトコルに関する情報を含む構造体です。事前に構築されたHlapiの NetworkedDataHandler
の多くでは、そのハンドラが意図する送受信パターンを定義するために、構築時に NetworkedDataDescriptor
が必要になります。
NetworkedDataDescriptorExtension
には、よく使用されるパターン(権限者→監視者、監視者→権限者、全員→全員)を生成するためのボイラープレートメソッドがいくつか用意されています。
メッセージの受け渡し
メッセージはどのように送信されますか?
Hlapiは、HlapiSessionの SendQueuedData
メソッドで呼び出されます。デフォルトではUnityのUpdateループごとに1回呼び出されます。 SendQueuedData
を呼び出す頻度を手動で制御するには、GetOrCreateManagedSession
ではなく、コンストラクターで HlapiSession
を作成します。
SendQueuedData
が呼び出されると、 HlapiSession
は現在登録されている NetworkedGroups
に対してそれぞれクエリを実行します。これにより、グループに登録されている NetworkedDataHandler
にそれぞれクエリが実行されます。そこから、 NetworkedDataHandler
はそれぞれ、ネットワーク上に送信すべきアップデート(位置のアップデートや新しいメッセージなど)があるかどうかを判断し、そのデータをオブジェクト(または特定のオブジェクト NetworkedDataHandlerBase.NothingToWrite
)として返します。
続いて、 NetworkGroup
ごとに、データをパッケージ化して に渡します。ここで照合され、必要なメタデータを付加してシリアライズ``HlapiSession``され、ネットワークを介して関連するピアに送信されます。
上記の処理はセッション内のピアごとに1回実行され、各 NetworkedDataHandler
はそのピアに送信するデータがあるかどうかを判断します。これにより、すべてのデータをすべてのピアに送信するのではなく、さまざまなピアが選択的に一部のメッセージを送受信することができます。
メッセージはどのように受け取りますか?
Hlapiは、Hlapiメッセージタグの付いたメッセージを受け取ると、そのメッセージが上記の形式でパッケージされたデータであると仮定し、メッセージに含まれるグループデータを解凍して、正しい NetworkGroup
に送ります。まだ HlapiSession
に登録されていない NetworkGroup
宛のメッセージを受け取った場合、そのメッセージはキャッシュに保存され、 NetworkGroup
が登録されると処理されます(ただし、この処理は TransportType
の信頼性が高い場合にのみ行われ、信頼性の低いメッセージは廃棄されます)。
そこから NetworkGroup
は、登録した NetworkedDataHandlers
に対して同様のメッセージの解凍とアドレス指定を行います(信頼性が高い場合は、未知のハンドラへのメッセージのキャッシュも行います)。最後に、 NetworkedDataHandlers
は相手から送信されたメッセージを他のデバイスから受信し、そのデータで処理を行います。たとえば、UnreliableBroadcastTransformPacker
は、受信するすべてのデータが PackedTransform
であり、そのGameObjectの更新位置が含まれることを把握しているのに対し、 GreedyAuthorityReplicator
は Role
の要求をピアから受信しようとしていることを把握しています。
Hlapiのメッセージはどのようにシリアライズされますか?
Hlapiでは、ARDKに付属している GlobalSerializerシステム が使用されます。