NeuroGoblin
NeuroGoblin6mo ago

What's the best way to change scenes across all clients?

Hi guys! As per the title, my application requires that all users be in a certain room at a certain time. I don't seem to be able to trigger this accross a second client (webXR build), only my local machine. This is my SceneSyncModel: [RealtimeModel] public partial class SceneSyncModel { [RealtimeProperty(1, true, true)] private string _currentScene; [RealtimeProperty(2, true, true)] private string _nextScene; [RealtimeProperty(3, true, true)] private bool _isSceneChanging; } On load, I locally set the nextScene string: public string nextScene; void Awake() { nextScene = SceneManager.GetActiveScene().name == "Admin" ? "LobbyNetworkTest" : "Admin"; } Then, once the realtime room has connected, I call SetNextScene(), which updates the model: public void SetNextScene() { model.nextScene = nextScene; // local reference as above } Then, when ready, I set the changing bool to true: public void SetIsSceneChanging(bool isChanging) { model.isSceneChanging = isChanging; } which then successfully fires a delegate: private void IsSceneChangingDidChange(SceneSyncModel model, bool isChanging) { // if true, trigger scene switch if (isChanging) { // Set bool to false so that on next scene load it is in the correct state SetIsSceneChanging(false); Debug.Log("IsChanging was true, switching to " + model.nextScene); SceneManager.LoadScene(model.nextScene); } else { Debug.Log("IsChanging was false, didn't switch"); } } This works locally, but doesn't seem to trigger the scene change on my other client. Please let me know if you need any more info!
18 Replies
kapa.ai
kapa.ai6mo ago
Hi @NeuroGoblin. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided, it seems like you're on the right track with using a RealtimeModel to synchronize scene changes across all clients. However, it's important to note that Normcore synchronizes all updates once per network frame (~20hz) and groups them into the same packet. When model updates are applied, they’re applied one at a time, and a change event fires for that value. However, it’s possible the other values from that packet hadn’t yet been applied. In order to get an event that fires once all updates have been applied to a model, you can use RealtimeCallback source (https://normcore.io/documentation/room/common-questions#sometimes-when-i-log-the-values-on-my-model-from-inside-of-valuedidchange-not-all-the-values-that-i-set-on-another-client-update-when-are-updates-sent-out-and-how-are-they-applied). Also, ensure that the RealtimeComponent is correctly set up to synchronize the scene and the model to match. When a RealtimeComponent is first created, Realtime will create a fresh model instance in which each RealtimeComponent can store data. If the object already exists on the server, the model will be prepopulated with the current state before it is given to the RealtimeComponent source (https://normcore.io/documentation/realtime/realtimecomponent). If the issue persists, it might be helpful to check the ownership of the RealtimeComponent. Normcore uses the concept of ownership to determine which client's scene should be used as the source of truth. You can check if the component is owned by the local client using the isOwnedLocallySelf or isOwnedLocallyInHierarchy properties source (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeComponent%601). Lastly, ensure that the Realtime instance managing the component has successfully connected to the room before attempting to change scenes. You can check this using the room property of the RealtimeComponent source (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeComponent%601). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai6mo ago
<@196555254496493568> kapa.ai is still learning and improving, please let us know how it did by reacting below
Mechabit
Mechabit6mo ago
you're disconnecting before the message is sent what you can do is wait a second before disconnecting
Mechabit
Mechabit6mo ago
which will let you know when a model as successfully been added to the server
NeuroGoblin
NeuroGoblin6mo ago
Thanks for the quick reply - in the former solution, would I use a coroutine or similar to wait right before SceneManager.LoadScene(model.nextScene); ? i'm guessing that's where the disconnect happens
Mechabit
Mechabit6mo ago
the didchange event will fire instantly locally rather than after the server gets the message so adding a yield after that would work this will work most of the time for sure but if you want to be 100% sure you can use the string key method
NeuroGoblin
NeuroGoblin6mo ago
something like this ? private IEnumerator ChangeSceneAfterWaiting() { yield return new WaitForSeconds(3f); SceneManager.LoadScene(model.nextScene); } private void IsSceneChangingDidChange(SceneSyncModel model, bool isChanging) { // if true, trigger scene switch if (isChanging) { // Set bool to false so that on next scene load it is in the correct state SetIsSceneChanging(false); StartCoroutine(ChangeSceneAfterWaiting()); } else { Debug.Log("IsChanging was false, didn't switch"); } }
Mechabit
Mechabit6mo ago
sure is your realtime persistent? cos if it isn't you wont need to change your trigger back to false
NeuroGoblin
NeuroGoblin6mo ago
not currently, i just have it duplicated across scenes
Mechabit
Mechabit6mo ago
I'm guessing it isn't or else you wouldn't be disconnecting on scene change you can remove that set false flag in case it messes up other players from getting the message
NeuroGoblin
NeuroGoblin6mo ago
i set it to dontdestroy on load and it still seems to disconnect on scene change (and deleted the instance in the second scene)
Mechabit
Mechabit6mo ago
your avatars also need to be persistent I mean non-persistent realtime is fine as well, typically you don't want scene models to be persistent the way I do it is I have 1 persistent realtime for avatars and messages and a 2nd realtime just for scene objects
NeuroGoblin
NeuroGoblin6mo ago
cool, so I have it setup like this:
No description
NeuroGoblin
NeuroGoblin6mo ago
with the realtimes having a different room name each. so on load, each client connects to both rooms. Then do i just need to make the PlayerAvatar dontdestroyonload? I want each client to have a different colour etc
NeuroGoblin
NeuroGoblin6mo ago
and the cube has a colorsync on it
No description
NeuroGoblin
NeuroGoblin6mo ago
and the avatar realtime will need to be persistent too ?
Mechabit
Mechabit6mo ago
it's up to you, you can make them non-persistent and have a realtime in every scene if you wanted your avatars to be persistent you set dontdestroyonload on them and the avatar realtime