For our metaverse experiment we wanted to have a very streamlined way to load in other scenes that the users would explore. We wanted this to be as transition-less as possible to not break immersion. Since this is something that all players must be able to see, we needed a way to let all players know that they need to load the scene.
To achieve this we will need some way to know when all players load the level. Most likely by receiving some kind of broadcast from the server. From there on they could be 2 possibilities. As seen before with networking it is possible to send a RPC (Remote Procedure Call) event across all of the users so that they know when to load in the scene. The idea for loading in the scene would be once a user enters a specific area this would trigger an event telling all of the other users to load in the scene.
How can we do either option?
First of all we need to find out how we can load a scene in Unity. Unity has a Scene Management library which allows you to load in scenes. Loading a scene will give you transition, this means that the user experience some kind of loading screen in VR that will probably break immersion. Another way to go about this is taking into consideration the possibility to be able to add scenes to the current scene.
In the unity editor we can also load in another scene into the current one also by dragging the scene you want to the hierarchy.
Loading a scene via the editor
Another way which was advised by Alexander was to have all objects in the scene and enable/disable them when needed.
This can be accomplished by disabling the scene in the editor window and re-enabling it when the scene needs to be loaded.
It was time to test both methods and see which was the best.
Since it was only 1 very small line of code to load in the scene additively I decided to start with that method. By placing a collider in the hallway that the user player walks through we can detect when we want to load the scenes. One thing I needed to keep in mind was that the collider needed to be a trigger, meaning that the collision box could be entered. Another important thing to keep in mind was that we needed some kind of trigger letting us know that the level CAN be loaded. Otherwise this would be triggered on every frame the trigger is entered which could cause some problems but also for keeping track if the scene has already been loaded or not.
Example of trigger
Scene loading methods used
First we check if the object that collides with the trigger has the Player tag AND that the canLoad trigger is not set to true. If so then we call the StartLoadScene method. By using the PhotonView component that is on the network manager we can call rpc events which we have made from our LoadScene method and let everyone in the room know we want to call the load scene method by using RpcRarget.All, afterwards we trigger our canLoad boolean.
It turns out that this method took quite a lot of time to load which led to massive frame drops and the user needing to wait about 5 seconds. looks like we need to try enabling the scene that is in the editor.
After adding the scene to the editor it was time to enable this instead of loading which I did by using the following bit of code in combination with the commented line from before.
Enabling the scene instead of loading.
The main difference here is that we use a parent GameObject that holds all the scene objects and set it to active when the user triggers the OnTriggerEnter event.
This approach turned out to work even better than the first, however we still had a brief few seconds of frame drops when the scene was enabled. This meant that we needed to shorten the loading time perhaps by loading in parts of the scene at a time.
This wasn't the most efficient way off doing this as we had a big perfomance issue, but it did give us the foundations of creating the current solution which was later taken over by Tirso. This turn out to be loading in pieces of the level bit by bit by using a coroutine.