Skip to main content

How to Display Shared Objects with Netcode

Multiplayer experiences need to display the same object in the same real-world location to multiple users during a Shared AR experience, and keep them synchronized. 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. Consult How to Use Shared AR for instructions on how to create a shared AR experience, and familarize with Netcode for GameObjects especially Object Spawning and Owner Authoritative Mode.
  2. Use either VPS Colocalization or Image Tracking Colocalization

Displaying Shared NetworkObjects

You can use Netcode's Object Spawning to display an object in the same place for everyone using a Shared AR experience. Follow these steps:

  1. Follow the steps to register a network spawning object in Unity, except instead of adding a NetworkObject component, add a LightshipNetworkObject. (This will automatically add a NetworkObject, too).

    Shared NetworkObjects
  2. Instantiate and spawn the object just as you would an NGO Object.

  3. Once it is instantiated and spawned, the object appears in the scene under XR Origin > Trackables > Persistent Anchor > ARLocation > SharedArRoot in the Hierarchy of your Unity scene on all connected devices in the same Lightship Room.

    Shared NetworkObjects

Synchronizing Device Positions to the Other Devices

You can use an NGO Object using Owner Authoritative Mode to synchronize peer device positions. This can use these to display player avatars in the correct position. Follow these steps:

  1. Create a prefab and register it in NetworkManager as a player prefab.
  2. Add a ClientNetworkTransform Component that extends NetworkTransform to the player prefab for a client authoritative player avatar.
  3. Add a NetworkBehaviour script to the player prefab that will update the location transform by copying the transform from the camera:
    // 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();
    }
    }
  4. Build and run this sample on two devices simultaneously. A player prefab should appear on each device in the session.

Tips for Efficient Synchronization

  • Minimize NetworkTransform, NetworkVariables usage and change.
    • Synchronizing many moving objects and/or synchronizing at high frequency using NetworkTransform can be expensive. Less frequent updates with interpolation can be useful to save network traffic.
    • Netcode update frequency in Netcode NetworkManager can be adjusted. Find “Tick Rate” field in the NetworkManager panel. Default is 30 times per second. Keep in mind this controls entire update frequency.

      Shared NetworkObjects