Skip to main content

How to Display Shared Objects with Netcode

AR multiplayer experiences need to display virtual objects in the same real-world location for multiple users and keep them synchronized. Using Unity's Netcode for Game Objects (NGO) system, You can also track the players' real-world device positions to use them as targets, get device positions relative to each other, display player status, or add other effects.

Prerequisites

  1. This How-To uses the project from Shared AR and Netcode as its base. If you have not completed it, start there.
  2. Your project will also need either VPS Colocalization or Image Tracking Colocalization.
  3. If you are unfamiliar with Netcode for Game Objects, read through Object Spawning and Owner Authoritative Mode before beginning.

Displaying Shared NetworkObjects

You can use Netcode's Object Spawning system to display an object in the same place for everyone in the same Shared AR experience.

To create and display a shared network object:

  1. Follow the steps to register a network spawning prefab in Unity.

    1. When instructed to add a NetworkObject Component, instead add a LightshipNetworkObject. (This will also automatically add a NetworkObject.)
    Shared NetworkObjects
  2. Instantiate and spawn the object as you would an NGO Object.

  3. Once the object is instantiated and spawned, it will appear in the Hierarchy under XR Origin > Trackables > Persistent Anchor > ARLocation > SharedArRoot. It should appear on all connected devices in the same Lightship Room.

    Shared NetworkObjects

Synchronizing Device Positions to the Other Devices

You can use an NGO Object in Owner Authoritative Mode to synchronize peer device positions and display player avatars in those positions.

To synchronize device positions:

  1. Create a prefab to track player positions. (If you have done this already as part of VPS Colocalization, you may skip this step):

    1. In the Hierarchy, right-click under the AR scene and select Create Empty. Name the new object playerPrefab.
    2. Drag playerPrefab from the Hierarchy to the Assets folder in the Project window to make it into a prefab, then delete it from the scene.
  2. In the Hierarchy, select NetworkManager, then, in the Inspector, assign playerPrefab to it.

  3. Add a ClientNetworkTransform Component to NetworkTransform to extend it to the player prefab and create a client-authoritative player avatar.

  4. Add the following NetworkBehaviour script to playerPrefab. This script updates the location by copying the transform to it from the camera.

    Click to reveal the NetworkBehaviour script
    // Copyright 2023 Niantic, Inc. All Rights Reserved.

    using Unity.Netcode.Components;

    using UnityEngine;

    public class PlayerAvatar: NetworkTransform
    {
    [HideInInspector]
    private Transform _arCameraTransform;

    protected override bool OnIsServerAuthoritative()
    {
    return false;
    }

    public override void OnNetworkSpawn()
    {
    if (IsOwner)
    {
    if (Camera.main)
    {
    _arCameraTransform = Camera.main.transform;
    }
    }

    base.OnNetworkSpawn();
    }

    new void Update()
    {
    if (IsOwner)
    {
    if (_arCameraTransform)
    {
    // Get local AR camera transform
    _arCameraTransform.GetPositionAndRotation(out var pos, out var rot);
    // Since using the ClientNetworkTransform, just update world transform of the cube matching with the
    // AR Camera's worldTransform. it's local transform will be synced.
    transform.SetPositionAndRotation(pos, rot);
    }
    }

    base.Update();
    }
    }
  5. Build and run this sample on two devices simultaneously. A player avatar should appear on each device in the session.

Tips for Efficient Synchronization

  • Minimizing usage and changes to NetworkTransform and NetworkVariables:
    • Using NetworkTransform to synchronize moving objects or synchronize at high frequency can be expensive. Updating less often and using interpolation to bridge the gaps can help cut down on synchronization costs.
    • The update frequency of the Netcode NetworkManager can also be adjusted. Select NetworkManager in the Hierarchy, then, in the Inspector, find the Tick Rate field. The default update frequency is 30 times per second, but you can lower this if need be to synchronize less often.

Shared NetworkObjects