Synchronizing objects across states using Normcore
Jennifer Wang, May 2022
This is a tutorial to set up synchronized objects in Unity Multiplayer with Normcore.
Learn more about Normcore at their website or here.
This tutorial essentially follows and expands on this 14 minute youtube video which I highly suggest you watch and follow first and look back here if you run into any issues or questions.
There are plenty of tutorials around that can help you get a VR game set up in Unity using the XR Interaction Toolkit, so this tutorial will mainly focus on integrating Normcore and assumes you have already set up your project with the XR Interaction Toolkit: (Note: 0:00-3:52 of the youtube tutorial linked above gets you set up with the XR Interaction Toolkit in Unity.)
(Download a custom Unity Template for VR that will save you from having to set up XR Interaction Toolkit manually each time)
Software: Unity 2019+, XR Interaction Toolkit, Normcore
Hardware: Quest 2 Headset, Windows or Mac + headset charging cable
Step 1:
Add an object to the scene that you would like to synchronize across states in your multiplayer app
Step 2:
Add the component Realtime Transform through inspector on the right side.
In Realtime Transform, you can select the attributes of the object you'd like to sync across views of different users
In Realtime View, under advanced settings, you can check prevent ownership takeover to prevent other players from interacting with the object if you have ownership over the object (if you have an object, others can't move it). You can also check destroy when owner or last client leaves to reset the object to its original state when the app first starts after a session ends.
Now when multiple users open the app, they should see the same object at the same position, rotation, and scale. If one person moves the object, this change should be reflected in others' views.
Step 3:
Add a script called GrabRequest as a component to the object you're synchronizing. The script should contain the following code. This allows multiple users to share ownership over the synchronized object. Note: make sure that your object is an interactable before adding this script. If the object is not an XRGrabInterable, then no one would be able to interact with the object.
using Normal.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class GrabRequest : MonoBehaviour
{
private RealtimeTransform realtimeTransform;
private XRGrabInteractable xRGRabInteractable;
// Start is called before the first frame update
void Start()
{
realtimeTransform = GetComponent<RealtimeTransform>();
xRGRabInteractable = GetComponent<XRGrabInteractable>();
}
// Update is called once per frame
void Update()
{
if (xRGRabInteractable.isSelected)
{
realtimeTransform.RequestOwnership();
}
}
}