Creating a connection splash screen in Unity
This recipe shows how to add a splash screen when a client connects to a Unity SDK project. If you’re looking for an introduction to using multiple scenes in a SpatialOS project, this is a good place to start.
You can use the Starter Project as the starting point for this recipe.
In this recipe, the splash screen has a button which the user clicks to attempt to connect to the game. If the connection is unsucccessful (for example, if SpatialOS isn’t ready for a client to connect), it fails. This implemenation is pretty basic - you can extend it if you want more complex menu functionality.
Here’s an example of what a splash screen might look like:
Creating a splash screen requires setting up your project to support multiple Unity scenes. This has already been done in the Starter Project, but you can find out how it’s done in the Loading from multiple scenes page.
1. Create the scene
Create the scene in the Unity
Assets
folder using theAssets > Create > Scene
drop-down menu.Give it a new name - for example,
SplashScreen
.Add the new scene name to
BuildSettings.cs
(inAssets/Gamelogic/Core
).public static readonly string UnityClientScene = "UnityClient"; public static readonly string SplashScreenScene = "SplashScreen";
- Add the new scene to the list of client scenes in
BuildSettings.cs
.
public static readonly string ClientDefaultActiveScene = UnityClientScene; public static readonly string[] ClientScenes = { UnityClientScene, SplashScreenScene };
- Add the new scene to the list of client scenes in
2. Add the splash screen content
Open the new
SplashScreen
scene and delete all theGameObjects
in it.Unity adds a camera and lighting to new scenes, but you’ll load this scene additively, so it will already have loaded the lighting and camera.
Create a new
Panel
using the drop-down menu:GameObject > UI > Panel
. This will also automatically create aCanvas
for you.Give the
Canvas
a new name - for example,SplashScreen
.Add a
Button
by selecting thePanel
and using the drop-down menu:GameObject > UI > Button
.Give it a new name - for example,
ConnectButton
.
This is how it should look:
The Unity Button
component provides an easy way to assign a callback for button presses, so you’ll add
a callback that tries to connect to the game.
3. Modify the Bootstrap script
You need to edit Bootstrap.cs
to provide a method that starts the connection to the game. This will be used by
the Connect
button callback later.
In
Bootstrap.cs
, add the followingConnectToClient()
method for the splash screen to call:public void ConnectToClient() { SpatialOS.Connect(gameObject); }
- Move the line
SpatialOS.Connect(...)
to the location in the snippet below. This is because you only want it to be called by UnityWorkers; UnityClients will connect using the splash screen.
public void Start() { ... switch (SpatialOS.Configuration.WorkerPlatform) { case WorkerPlatform.UnityWorker: Application.targetFrameRate = SimulationSettings.TargetServerFramerate; SpatialOS.OnDisconnected += reason => Application.Quit(); SpatialOS.Connect(gameObject); // Move the line here break; case WorkerPlatform.UnityClient: Application.targetFrameRate = SimulationSettings.TargetClientFramerate; SpatialOS.OnConnected += CreatePlayer; break; } // This is where you needed to move the line `SpatialOS.Connect(...)` from }
- Move the line
At the top of the script, add the following import:
using UnityEngine.SceneManagement;
- Inside UnityClient’s
case
, add a line to load theSplashScreen
scene . UseAdditive
mode since you want to load this scene on top of a currently loaded one:
SceneManager.LoadSceneAsync(BuildSettings.SplashScreenScene, LoadSceneMode.Additive);
- Inside UnityClient’s
The Start()
method should look like this:
using UnityEngine.SceneManagement;
...
public void Start()
{
...
switch (SpatialOS.Configuration.WorkerPlatform)
{
case WorkerPlatform.UnityWorker:
Application.targetFrameRate = SimulationSettings.TargetServerFramerate;
SpatialOS.OnDisconnected += reason => Application.Quit();
SpatialOS.Connect(gameObject);
break;
case WorkerPlatform.UnityClient:
Application.targetFrameRate = SimulationSettings.TargetClientFramerate;
SpatialOS.OnConnected += CreatePlayer;
SceneManager.LoadSceneAsync(BuildSettings.SplashScreenScene, LoadSceneMode.Additive);
break;
}
}
public void ConnectToClient()
{
SpatialOS.Connect(gameObject);
}
4. Handle the button press
Create a script called
SplashScreenController.cs
on theSplashScreen
Unity canvas, which receives the button press event, and calls theAttemptConnection()
method:using Assets.Gamelogic.Global; using Assets.Gamelogic.Utils; using Improbable.Unity.Core; using UnityEngine.UI; public class SplashScreenController : MonoBehaviour { [SerializeField] private Button ConnectButton; public void AttemptSpatialOsConnection() { DisableConnectionButton(); AttemptConnection(); } private void DisableConnectionButton() { ConnectButton.interactable = false; } private void AttemptConnection() { FindObjectOfType<Bootstrap>().ConnectToClient(); StartCoroutine(TimerUtils.WaitAndPerform(SimulationSettings.ClientConnectionTimeoutSecs, ConnectionTimeout)); } private void ConnectionTimeout() { if (SpatialOS.IsConnected) { SpatialOS.Disconnect(); } ConnectButton.interactable = true; } }
In the script above:
Changing the button
interactable
property prevents the user sending multiple attempts to connect at once.Using a coroutine in
TimerUtils
and theClientConnectionTimeoutSecs
duration makes the user wait before trying to connect again (you’ll set this value in the next step).The
SpatialOS.Disconnect()
method call tidies up any Unity components created in the failed connection attempt.
- In
SimulationSettings.cs
, add a new constant (you can set it to a different value):
public static readonly float ClientConnectionTimeoutSecs = 7;
Attach the
ConnectButton
to theSplashScreenController.cs
script on theSplashScreen
GameObject
by dragging and dropping it into itsConnectButton
field.Connect the button clicks to the
AttemptSpatialOsConnection()
method by adding it to the button’sOnClick()
functions list:Beneath the
On Click ()
section, on the right, click the+
button.Next to
None (object)
click the circle icon. In the drop-down that opens, select theSplashScreen
scene.Click where it says
No function
. In the drop-down menu, selectSplashScreenController > AttemptSpatialOsConnection ()
.
5. Hide the splash screen
All that remains is to remove the splash screen once the player is connected, ie when the Player
entity has been
created.
To check for this:
Open a script on the
Player
where the connecting user’s client has write access.In the Starter Project, you can use
SendClientConnection.cs
.Add the following import statement:
using UnityEngine.SceneManagement;
- In
OnEnable()
, include the following:
SceneManager.UnloadSceneAsync(BuildSettings.SplashScreenScene);
- In
6. Test that it worked
- Build workers: in the SpatialOS window (
Window > SpatialOS
), underWorkers
, clickBuild
. - Under
Run SpatialOS locally
, clickRun
. - Connect a UnityClient by opening the UnityClient scene, then pressing play
Play
in your Unity project. You should see:
- The
SplashScreen
being loaded when the Unity client is started. - When you press
Connect
, the connection to SpatialOS is made. - This causes the
Player
entity to be created, and theSplashScreen
scene to be unloaded.
That looks like this:
- The
If you want to improve this basic implementation, you could: