Hlapi Network Spawning Tutorial

How network spawning works with the High-level network API.

Introduction

Network spawning is the networked equivalent of Unity’s Instantiate method. Instead of spawning a GameObject and its MonoBehaviour components on a single device, a pre-registered NetworkedUnityObject is spawned, and a network message containing the relevant information is sent to peers so that they can spawn an identical object.

The NetworkedUnityObject script contains plumbing to register the newly spawned object to the HlapiSession and ensure that all NetworkedDataHandlers on the object are synced with their counterparts on other devices.

Setting Up the Prefab Manifest

  1. For all objects that will be network spawned, attach the NetworkedUnityObject and AuthBehaviour components (most of the time, you will want an NetworkedBehaviour as well, to define the behaviour of the object).

    ../../../_images/networkedbehaviour.png
  2. Create a PrefabManifest asset by navigating to Asserts> Create> Networking> Spawning> PrefabManifest.

    ../../../_images/prefabmanifest.png
  3. Add prefabs of all the objects that will be network spawned to the PrefabManifest (change the number of elements to expand or shrink the list).

    ../../../_images/pfmaninspector.png
  4. Finally, add the NetworkSceneSpawnManifest component to your scene.

    ../../../_images/networkspawnmanifest.png

Network Spawning Objects

With the manifest set up, network spawning an object requires just one API call.

// Reference set in the Inspector
public NetworkedUnityObject _objectToNetworkSpawn;

void SpawnObjectForAllPeers()
{
  NetworkedUnityObject spawnedInstance = _objectToNetworkSpawn.NetworkSpawn();
}

Network Destroying Objects

With a reference to a NetworkedUnityObject, network destroying is as simple as:

void DestroyNetworkedUnityObject(NetworkedUnityObject objectToDestroy)
{
  objectToDestroy.NetworkDestroy();
}

The valid destructors of each NetworkedUnityObject can be set on the prefab through the Editor.

../../../_images/network_destroy_options.png

ARDK will attempt to propagate a network destroy message for any objects that are destroyed on Unity scene close or through UnityEngine.Destroy. If a peer is not a valid destructor of the object, ARDK cannot prevent a UnityEngine.Destroy, but the message will not be propagated.

Furthermore, there is no guarantee that a message will be propagated when the scene is unloaded, as the MultipeerNetworking session may have already been disposed. For NetworkedUnityObjects that should be cleaned up when their valid destructor leaves (i.e., a peer’s avatar that should not be left floating in midair after the peer leaves), enable the DestroyIfDestructorLeaves option to handle cleanup locally on each device. If multiple peers can destroy the object, the first peer that leaves will trigger the local cleanup.

Implementation Details of Network Spawning

What is actually happening with NetworkedUnityObjects, NetworkGroups, and NetworkBehaviours when an object is NetworkSpawned?:

  1. A regular GameObject or Prefab has a NetworkedUnityObject component attached to it, making it a NetworkedUnityObject and automatically adding an AuthBehaviour component. At this point any other NetworkedBehaviours can be created and added to the NetworkedUnityObject. Our editor script NetworkedUnityObjectEditor will automatically assign a RawId and PrefabId to the NetworkedUnityObject and populate the Behaviours list.

  2. The created NetworkedUnityObject is registered to a PrefabManifest asset, which is loaded on scene start through the NetworkSceneSpawnManifest component. This step ensures that all peers in the session with the same build have a shared understanding of which NetworkedUnityObjects are available for spawning. It is important to rebuild all clients if updating the PrefabManifest, otherwise a NetworkedUnityObject may be spawned that older clients are not aware of.

  3. A client calls NetworkSpawn on a NetworkedUnityObject. This will immediately instantiate the object on the client that calls NetworkSpawn, and assigns a randomly generated RawId to the new object. The client then serializes all spawning information (transform, PrefabId, RawId, etc) and sends that information to other clients in the session.

    1. The clients that receive the spawning information will attempt to find the requested PrefabId in their loaded PrefabManifest, and instantiate the corresponding NetworkedUnityObject once it does.

  4. After instantiating the NetworkedUnityObject, the NetworkSpawner calls NetworkedUnityObject.Initialize(), which creates a new NetworkGroup using the randomly generated RawId (which has been replicated for all clients). This step ensures that all NetworkedDataHandlers created and attached to the NetworkedUnityObject will automatically send data to the correct NetworkGroup.

  5. NetworkedUnityObject.Initialize() will then call each attached NetworkedBehaviour.Initialize(), which will sort the initialization of all attached NetworkedBehaviours by their order (defined in the overridden NetworkedBehaviour.SetupSession) and execute each SetupSession in order. At this point, all NetworkedDataHandlers (such as NetworkedFields, MessageStreamReplicators, etc) that are created in SetupSession are created and registered to the Hlapi system, and can start sending and receiving data.

See Also

Low level networking

The high level networking API (Hlapi)