Multiplayer AR
Creating Multiplayer AR Experiences with MultiSet VPS SDK for Unity
The MultiSet Visual Positioning System (VPS) SDK for Unity empowers developers to build immersive, multiplayer Augmented Reality experiences. A core component of this is the ability for all users who localize within the same physical map to share a unified coordinate system. This synchronization allows for the seamless interaction of users and virtual objects in a shared AR space. Once this shared coordinate system is established, developers can leverage existing Unity networking solutions, such as Netcode for GameObjects or third-party assets like Photon, to broadcast and stream player coordinates across a local or global network, depending on the application's requirements.
Establishing a Shared Coordinate System
The MultiSet SDK achieves a shared coordinate system through its "Map Space" GameObject. When a user's device successfully localizes within a pre-scanned map, the MultiSet SDK transforms the MapSpace GameObject to align perfectly with the physical environment. This means that for every user localized in the same map, their individual MapSpace will have the exact same position and orientation in the real world.
This MapSpace then acts as the anchor for all AR content. By placing all shared virtual objects and player representations as children of the MapSpace GameObject, developers can ensure that these elements appear in the same real-world location for all users.
Player Coordinate Transformation
While each player's AR camera will have its own unique world coordinates within their respective Unity scenes, these can be transformed into a local coordinate system relative to the shared MapSpace. This local position is what should be synchronized across the network. By doing so, even if players start their AR experience from different points within the map, their relative positions within the shared AR space will be consistent.
The key to this transformation is to calculate the local position of the player's AR camera with respect to the MapSpace. This can be achieved using Unity's Transform.InverseTransformPoint method. This method takes a world position (in this case, the AR camera's position) and converts it into a local position relative to the specified transform (the MapSpace).
Vector3 cameraRelative = mapSpace.transform.InverseTransformPoint(Camera.main.transform.position);
This cameraRelative vector can then be broadcast over the network to other players. On the receiving end, each client can use this local position to place a representation of the remote player within their own MapSpace, ensuring that all players see each other in the correct relative positions.
Sample Script: PlayerPositionManager
The following C# script demonstrates how to obtain the current AR camera's position relative to the MapSpace and provides a basic structure for managing player positions in a multiplayer AR scene.
Instructions:
Create a new C# script named PlayerPositionManager.
Attach this script to a GameObject in your scene, for example, a "GameManager" or the player's root object.
In the Unity Inspector for this script, drag your scene's main AR Camera to the arCamera field and the MapSpace GameObject to the mapSpace field.
using UnityEngine;
/// <summary>
/// Manages the player's position relative to the shared MapSpace.
/// This script demonstrates how to get the local position of the AR camera
/// within the MapSpace's coordinate system, which can then be used for
/// multiplayer networking.
/// </summary>
public class PlayerPositionManager : MonoBehaviour
{
[Tooltip("The main AR camera representing the user's viewpoint.")]
public Camera arCamera;
[Tooltip("The GameObject that is moved and oriented by the MultiSet SDK upon successful localization.")]
public GameObject mapSpace;
// This would be the player's local position within the shared AR space.
// In a real multiplayer setup, you would continuously update and broadcast this vector.
private Vector3 localPlayerPosition;
void Update()
{
// Ensure both the AR camera and MapSpace have been assigned.
if (arCamera != null && mapSpace != null)
{
// Calculate the camera's position relative to the MapSpace.
// This gives us a coordinate within the shared AR space.
localPlayerPosition = mapSpace.transform.InverseTransformPoint(arCamera.transform.position);
// For demonstration purposes, we'll log the local position.
// In a multiplayer application, you would send 'localPlayerPosition'
// to other players over the network.
Debug.Log("Player's Local Position in MapSpace: " + localPlayerPosition);
}
else
{
if (arCamera == null)
{
Debug.LogError("AR Camera has not been assigned in the PlayerPositionManager.");
}
if (mapSpace == null)
{
Debug.LogError("MapSpace has not been assigned in the PlayerPositionManager.");
}
}
}
/// <summary>
/// This is a placeholder function to illustrate where you would integrate
/// your networking logic to send the player's position.
/// </summary>
void BroadcastPlayerPosition()
{
// Example: Using a hypothetical networking service to send the local position.
// YourNetworkingSolution.SendPosition(localPlayerPosition);
}
/// <summary>
/// This is a placeholder function to illustrate how you would receive
/// a remote player's position and update their representation in the scene.
/// </summary>
/// <param name="remotePlayerId">A unique identifier for the remote player.</param>
/// <param name="remotePosition">The local position of the remote player within the MapSpace.</param>
public void UpdateRemotePlayerPosition(string remotePlayerId, Vector3 remotePosition)
{
// Find the GameObject representing the remote player.
// GameObject remotePlayerObject = FindRemotePlayer(remotePlayerId);
// If the remote player object exists, update its local position within the MapSpace.
// if (remotePlayerObject != null)
// {
// remotePlayerObject.transform.SetParent(mapSpace.transform);
// remotePlayerObject.transform.localPosition = remotePosition;
// }
}
}
Last updated
Was this helpful?