Hlapi FAQ
Frequently Asked Questions about the High-level networking API.
Networked Unity Objects
How do I create my own NetworkedBehaviour?
Like extending MonoBehaviour allows a script to integrate with Unity events and systems, extending a NetworkedBehaviour allows for integrating with the Hlapi. Each NetworkedBehaviour
that is attached to a NetworkedUnityObject and is registered to that object’s Behaviours
list (through the Editor) will automatically be initialized whenever that object is network spawned. This allows for registering NetworkedDataHandlers to the provided Group
without having to worry about object lifetimes or tagging, as that will be handled by the Hlapi.
For example, the following script demonstrates implementing a NetworkedBehaviour
that sets up Transform
and Color
replication. As each spawned NetworkedUnityObject
has its unique NetworkGroup
, writing to any of these NetworkedDataHandlers will only affect the corresponding object on other devices.
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(); } }
What’s the NetworkedDataDescriptor used for?
The NetworkedDataDescriptor
is a struct that contains information regarding authorized senders and receivers, as well as the networking protocol. Many of the prebuilt Hlapi NetworkedDataHandler
require a NetworkedDataDescriptor
on construction, to define the intended sending/receiving pattern of that handler.
The NetworkedDataDescriptorExtension
provides a few boilerplate methods to generate commonly used patterns (Authority → Observers, Observers → Authority, and Any → Any).
Message Passing
How are messages sent?
The Hlapi is driven by the SendQueuedData
method in the HlapiSession, which by default is called once per Unity Update loop. To manually control the frequency of calling SendQueuedData
, create an HlapiSession
through its constructor, rather than through GetOrCreateManagedSession
.
When SendQueuedData
is called, the HlapiSession
will query each of the NetworkedGroups
currently registered to it, which will in turn query each NetworkedDataHandler
that is registered to the group. From there, each NetworkedDataHandler
determines if it has some update to send over the network (for example, an updated position, or a new message) and returns the data as an object (or a specific object NetworkedDataHandlerBase.NothingToWrite
).
Each NetworkGroup
will then package the data and pass it up to the HlapiSession
, where it is collated, appended with the required metadata, serialized, and sent over the network to the relevant peers.
The above process is run once per peer in the session, and each NetworkedDataHandler
determines if it has some data to send to that peer. This allows for various peers to selectively receive or send some messages, instead of sending all data to all peers.
How are messages received?
When the Hlapi receives a message with the Hlapi message tag, it assumes that the message is data packaged in the above form, unpacks the group data pieces contained in the message, and sends them to the correct NetworkGroup
. If a message is received that is addressed to an NetworkGroup
that has not yet been registered to the HlapiSession
, the message will be cached and handled once that NetworkGroup
registers (but only if the TransportType
is reliable; unreliable messages will be dropped).
From there, the NetworkGroup
does a similar unpacking and addressing of messages to its registered NetworkedDataHandlers
(and caching messages to unknown handlers, if reliable). Finally, the NetworkedDataHandlers
will receive the message that was sent by their counterpart, from another device, and do something with that data. For example, the UnreliableBroadcastTransformPacker
knows that all data received will be a PackedTransform
, containing an updated position for its GameObject, while the GreedyAuthorityReplicator
knows that it is receiving an attempted Role
claim from a peer.
How are Hlapi messages serialized?
The Hlapi uses the GlobalSerializer system that is provided with ARDK.