Navigate Between Scenes Using ClientServerBootstrap
Code and workflows to navigate between NavigationScene and MainScene using UI buttons
What will be developed on this page

We will adding logic to navigate between NavigationScene and MainScene and properly handle creating and destroying ECS worlds.
Github branch link: https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample/tree/Navigating-Between-Scenes
Navigating from NavigationScene to MainScene
We have 3 views that could take us to MainScene:
HostGameScreen
JoinGameScreen
ManualConnectScreen

Rather than have separate logic in each of their associated custom Visual Elements (cVEs), we are going to create a new script that handles all transitions from NavigationScene to MainScene, named "ClientServerLauncher." We will pull in references to each of these views and will add callbacks to the "Host Game" and "Join Game" buttons that will trigger the transition. Like most software engineering, this is an opiniated decision for where to put the "brains" for transition. We have gotten feedback that we maybe we have abstracted too much, and made it more confusing which is a fair critique. We wanted to show all the different ways elements can interact in this UI section.
Later on in the next Multiplayer section we will add additional logic to ClientServerLauncher so that we can select which IP address we connect to as a client.
In this page we will implement ClientServerBootstrap to prevent triggering Client/Server world creation until we are ready to transition to MainScene and click one of our transition buttons.
Why? Well right now in the NavigationScene DOTS NetCode bootstrap does its thing and creates server/client worlds. We want to create a build where a user can "host" (which means be both client and server) or "join" (which means they are just a client. So we cannot make the decisions whether to build a server world in the NavigationScene, that decision should be made in MainScene (once we know what decision has been made).
Bootstraphe default bootstrap creates client server Worlds automatically at startup. It populates them with the systems defined in the attributes you have set. This is useful when you are working in the Editor, but in a standalone game, you might want to delay the World creation so you can use the same executable as both a client and server.
To do this, you can create a class that extends
ClientServerBootstrapto override the default bootstrap. ImplementInitializeand create the default World. To create the client and server worlds manually, callClientServerBootstrap.CreateClientWorld(defaultWorld, "WorldName");orClientServerBootstrap.CreateServerWorld(defaultWorld, "WorldName");.The following code example shows how to override the default bootstrap to prevent automatic creation of the client server worlds:
Currently, because we have the NetCode package installed, NetCode automatically creates Client/Server worlds when the application starts
If you don't have the NetCode package installed, please go visit the previous "DOTS NetCode" section for installation instructions
Click play while NavigationScene is open then navigate to the DOTS Windows and see that both Server and Client worlds are created

We want to limit the worlds to DefaultWorld while in NavigationScene
This is a preemptive measure we are taking because later on, in the Multiplayer section, we won't know whether we want to join a game as just a client or as a client/server, so we want to hold off on creating these NetCode worlds
So we will implement NetCodeBootstrap
I know it seems like we have repeated ourselves like 3 times but we have gotten feedback that "World creation delay" was a big confusing so we wanted to hammer the point home!
Un-click Play and right-click inside the Multiplayer Setup folder, select "Create" to create a new C# script called NetCodeBootstrap
Paste the code snippet below into NetCodeBootstrap.cs:

Please be patient! We noticed in our testing that it takes a couple tries for Unity to pick up this new bootstrap script ⏳
Now hit play in NavigationScene, then navigate to DOTS Windows to take a look at the available worlds

Good, NetCodeBootstrap has prevented automatic creation of worlds 👍
Only DefaultWorld is available
Now let's move onto creating ClientServerLauncher that will manually build (the previously automatically-created) Client and Server worlds
Right-click in the NavigationScene Hierarchy and create a new empty GameObject called "ClientServerLauncher"
Move it just below "LocalGamesDiscovery" in the scene Hierarchy
Add a component to the GameObject that is a new script named "ClientServerLauncher"
First create the file by right-clicking in the Multiplayer Setup folder and selecting Create > C# Script

🔑MAJOR KEY ALERT 🔑
It is recommended by Unity to create the Client and Server worlds BEFORE navigating to a scene with converted SubScenes (as opposed to first navigating to MainScene then creating client and server worlds).
When the scene is loaded it automatically triggers loading of all SubScenes it contains into all worlds. If you manually create the worlds you need to do so before you load the scene with your content or they will not stream in any sub-scenes. It would also be possible to manually trigger SubScene streaming - but in this case it would mean you need to manually keep track of all SubScenes.
Now let's update ClientServerLauncher
Paste the code snippet below into ClientServerLauncher.cs:
You'll notice that there are 3 key functions in ClientServerLauncher:
ServerLauncher (creates server world)
ClientLauncher (creates client world(s) if Thin Clients exist)
StartGameScene (triggers loading MainScene)
Depending on whether we click "Host Game" or "Join Game" we trigger 2 or 3 of these functions
We always trigger StartGameScene and ClientLauncher
We launch ServerLauncher only if we are a host

Select ClientServerLauncher in the Hierarchy, click Add Component in Inspector and add Client Server Launcher
Drag TitleScreenUI GameObject from the Hierarchy onto the "Title UI Document" field under the Client Server Launcher component in Inspector while ClientServerLauncher is still selected in Hierarchy
We now need to add our scenes to our build settings so we can navigate to them
Navigate to MainScene, go to "Build Settings..." and click "Add Open Scenes"
Return to NavigationScene, go to "Build Settings..." and click "Add Open Scenes"
Go to Multiplayer > PlayMode Tools > set the Num Thin Clients equal to 1

Hit play, and then click Host Game

We are now able to transition to MainScene with the proper amount of NetCode worlds
We created NetCodeBootstrap
We created ClientServerLauncher GameObject
Added a new script ClientServerLauncher
We updated ClientServerLauncher to trigger creation of client/server worlds and trigger a scene
We added our scenes to our build settings
We dragged TitleUI to our ClientServerLauncher's "Title UI Document" field
Navigating from MainScene to NavigationScene
Similar to how we created client/server worlds to transition to MainScene, we now need to destroy those client/server worlds when we return to NavigationScene. We will also delete all entities created so we can start again in NavigationScene with a "blank slate".
Let's update our ClientServerConnectionHandler to be able to take over these new "clean-up" duties
We think this is a good place to put "clean-up" functionality because it's part of handling the connection between servers and clients
Paste the code snippet below into ClientServerConnectionHandler.cs:
Within MainScene, click on ClientServerConnectionHandler in the Hierarchy and drag the GameUI GameObject (also in Hierarchy) onto the "Game UI Document" field under Client Server Connection Handler component in Inspector, save, and navigate back to NavigationScene

Hit play, host a game, play around, quit, and host again

Note that hitting play in MainScene will no longer trigger starting the gameplay
This is because client/server worlds are created in NavigationScene
Note that hitting "Join Game" will not trigger gameplay because we are not connected to a server
This will be updated in the Multiplayer section
We are now able to navigate back to NavigationScene by hitting the "Quit Game" button in MainScene
We updated ClientServerConnectionHandler
Github branch link:
git clone https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample/
git checkout 'Navigating-Between-Scenes'
Last updated