xulipa
xulipa5mo ago

Changing scene room duplicates XR Origin

When I change room and scene it seems to keep my XR Origin Rig, so everytime I change room/scene it creates a new one. I have seen some people just remove their XR origin rigs of the scene they are going to. However I have different Rigs for each scene, so I need to leave the XR rigs in the scene. So I'm thinking I need to destroy some before I connect to a new room? Here is my code: using System.Collections; using System.Collections.Generic; using UnityEngine; using Normal.Realtime; using UnityEngine.SceneManagement; using UnityEngine.XR.Interaction.Toolkit; public class NormalSceneLoader : MonoBehaviour { [SerializeField] private Realtime realtime; [SerializeField] private string roomName; [SerializeField] private int sceneIndex; private XRGrabInteractable grabInteractable; private bool isLoading; void Start() { grabInteractable = GetComponent<XRGrabInteractable>(); grabInteractable.selectEntered.AddListener(OnSelectEntered); } void OnSelectEntered(SelectEnterEventArgs args) { LoadScene(); } public void LoadScene() { if (isLoading) return; isLoading = true; realtime.Disconnect(); realtime = null; SceneManager.LoadScene(sceneIndex); realtime = FindObjectOfType<Realtime>(); realtime.Connect(roomName); isLoading = false; } }
10 Replies
kapa.ai
kapa.ai5mo ago
Hi @xulipa. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- It seems like you're experiencing an issue where a new XR Origin Rig is created every time you change rooms or scenes. This could be due to the fact that your XR Origin Rigs are not being properly cleaned up when you switch scenes. In your current code, you're disconnecting from the room and setting realtime to null before loading a new scene. However, you're not explicitly destroying the XR Origin Rig. This could be why you're seeing duplicates. One way to handle this is to destroy the XR Origin Rig before you load a new scene. You can do this by finding the XR Origin Rig in your scene and calling Destroy() on it. However, you mentioned that you have different Rigs for each scene, so you need to be careful to only destroy the Rig that's currently in use. Here's an example of how you might modify your LoadScene() method to destroy the current XR Origin Rig:
public void LoadScene()
{
if (isLoading) return;
isLoading = true;
realtime.Disconnect();
realtime = null;

// Find the current XR Origin Rig and destroy it
XRInteractionManager xrInteractionManager = FindObjectOfType<XRInteractionManager>();
if (xrInteractionManager != null)
{
Destroy(xrInteractionManager.gameObject);
}

SceneManager.LoadScene(sceneIndex);

realtime = FindObjectOfType<Realtime>();
realtime.Connect(roomName);

isLoading = false;
}
public void LoadScene()
{
if (isLoading) return;
isLoading = true;
realtime.Disconnect();
realtime = null;

// Find the current XR Origin Rig and destroy it
XRInteractionManager xrInteractionManager = FindObjectOfType<XRInteractionManager>();
if (xrInteractionManager != null)
{
Destroy(xrInteractionManager.gameObject);
}

SceneManager.LoadScene(sceneIndex);

realtime = FindObjectOfType<Realtime>();
realtime.Connect(roomName);

isLoading = false;
}
This code finds the XRInteractionManager in your scene, which should be a component on your XR Origin Rig, and destroys its associated game object. This should effectively remove the current XR Origin Rig from your scene. Please note that this is a general solution and might need to be adapted based on your specific project setup. Also, remember to be careful when destroying objects, as it can lead to unexpected behavior if not handled correctly. For more information on how to manage objects in Normcore, you can refer to the Normcore Documentation (https://normcore.io/documentation/realtime/realtimecomponent#using-views-and-components-in-a-scene). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@725231244169707600> kapa.ai is still learning and improving, please let us know how it did by reacting below
Mechabit
Mechabit5mo ago
the only reason that your xrorigin isn't being destoryed on scene change is that DontDestroyOnLoad was called on it at some point, just do a search for that code in your IDE and remove it.
xulipa
xulipaOP5mo ago
So that's some native Unity system code I would be looking for?
Mechabit
Mechabit5mo ago
it's nothing in normcore doing it for sure
xulipa
xulipaOP5mo ago
Because in this video I see that they are removing their XR Origin from the scene. Which I cannot because I'm using a different XR Origin for every scene: https://www.youtube.com/watch?v=AGMKZcL_CuI
Black Whale Studio - XR Tutorials
YouTube
Part 3: Normcore Scene Loading & Sessions Management - Make a Multi...
In this video we will learn how to create multiple rooms and switch between them. As always, we will explain to you the Normcore documentation and then jump into the code and test our project. We hope you are enjoying this video, if so, please consider supporting us below! Resources: 🔗 Normcore Official Website: https://normcore.io/ 🔗 Normcor...
Mechabit
Mechabit5mo ago
nothing wrong with have a different xr origin in each scene
xulipa
xulipaOP5mo ago
@Normcore Assistant can you change the script into Additive Scene/Room loading instead
kapa.ai
kapa.ai5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Sure, you can modify your script to use additive scene loading. This can be done using SceneManager.LoadSceneAsync() with LoadSceneMode.Additive. This will load the scene asynchronously in the background, without unloading the current scene. Here's how you might modify your LoadScene() method to use additive scene loading:
public void LoadScene()
{{
if (isLoading) return;
isLoading = true;

// Disconnect from the current room
realtime.Disconnect();

// Load the new scene additively
SceneManager.LoadSceneAsync(sceneIndex, LoadSceneMode.Additive).completed += OnSceneLoaded;
}}

private void OnSceneLoaded(AsyncOperation operation)
{{
// Find the Realtime component in the newly loaded scene
realtime = FindObjectOfType<Realtime>();

// Connect to the new room
realtime.Connect(roomName);

isLoading = false;
}}
public void LoadScene()
{{
if (isLoading) return;
isLoading = true;

// Disconnect from the current room
realtime.Disconnect();

// Load the new scene additively
SceneManager.LoadSceneAsync(sceneIndex, LoadSceneMode.Additive).completed += OnSceneLoaded;
}}

private void OnSceneLoaded(AsyncOperation operation)
{{
// Find the Realtime component in the newly loaded scene
realtime = FindObjectOfType<Realtime>();

// Connect to the new room
realtime.Connect(roomName);

isLoading = false;
}}
In this code, OnSceneLoaded is a callback method that's called when the scene has finished loading. This is where you find the Realtime component in the new scene and connect to the new room. Please note that when using additive scene loading, you'll end up with multiple scenes loaded at the same time. If you want to unload the previous scene after the new one has loaded, you can do so using SceneManager.UnloadSceneAsync(). Also, remember that when using additive scene loading, each scene will have its own set of game objects, and these are not automatically cleaned up when you load a new scene. You'll need to manage this yourself, for example by destroying any game objects that you don't need anymore. For more information on how to manage scenes in Unity, you can refer to the Unity Documentation on Scene Management (https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.html). For more information on how to manage rooms in Normcore, you can refer to the Normcore Documentation (https://normcore.io/documentation/realtime/realtimecomponent#using-views-and-components-in-a-scene). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@725231244169707600> kapa.ai is still learning and improving, please let us know how it did by reacting below