Using Both HLAPI and LLAPI

If possible, you should avoid using both HLAPI and LLAPI in your app to reduce complexity. However, if you have to use both HLAPI and LLAPI in your AR experience, be aware of the following considerations.

Verifying Message Tags

Each HlapiSession uses a single message tag for all of its messages (set when the session is constructed), so it is possible to use the Hlapi for some functionality (i.e. network spawning), while sending and parsing raw byte messages via LLAPI for other networked functionality. In this case, it is especially important to keep track of what message tags are being used, to avoid conflicting messages from the two systems.

The following code example uses both HLAPI and LLAPI, and checks the message tag in a PeerDataReceived delegate to verify the message is a LLAPI message that needs to be processed, and not an HLAPI message.

using Niantic.ARDK.AR.Networking;
using Niantic.ARDK.Networking.HLAPI.Object.Unity;

// Reference set in Inspector
public NetworkedUnityObject _objectToNetworkSpawn;

// Enum list containing all message tags used in the application
public enum GameActionMessageTags : uint
{
 // Other game actions
 PerformSomeGameAction = 40U,
 // ...
}

// Use the Hlapi to network spawn an object across all peers
void SpawnObjectForAllPeers()
{
  // Note that NetworkSpawn is an extension method coming from NetworkSpawner
  _objectToNetworkSpawn.NetworkSpawn();
}

void PerformActionForAllPeers(IMultipeerNetworking networking, byte[] gameData)
{
  networking.BroadcastData(GameActionMessageTags.PerformSomeGameAction, gameData, TransportType.UnreliableUnordered);
}

void SubscribeToPeerDataReceived(IMultipeerNetworking networking)
{
  networking.PeerDataReceived += OnPeerDataReceived;
}

// Since the Hlapi also uses byte messages, this will be fired each time an object is NetworkSpawned as well
void OnPeerDataReceived(PeerDataReceivedArgs args)
{
  // Check that it is a message we care about, rather than an Hlapi message
  if(args.Tag != GameActionMessageTags.PerformSomeGameAction)
  {
    return;
  }

  // We now know this is the message that this class cares about, so use the data to perform some update
}