Sunday, 20 March 2016

Loading Screen

This is another quick tutorial on loading screens.

A loading screen is the most common way to show he user that the game is running and it provides a visual representation of the loading process.

First, I create a canvas called LoadingCanvas, which is going to contain an Image, called Loading Screen. Then, I add two more components and I place them as children of the image: a slider and a text. (Fig 1).

Fig 1

The text simply says "Loading..." and the slider will be used to show the loading progress.

Then other canvas you see in Fig 1 contains a button which, when pressed, will just load the next scene.

In Fig 2 we can see what the loading screen looks like.

Fig 2
The image is stretched so as to cover the entire canvas, and the 2 UI child elements are anchored and positioned to the center. Also, the LoadingCanvas has an additional component called CanvasGroup. I use this so I can modify the alpha parameter to turn the whole canvas invisible.

To put the loading screen to use we need 2 scripts: one for the actual loading screen, which will simply pass values to the slider, the other one is called by the button, which will activate the loading screen and pass the float value to it to be handed to the slider.

The first script, called LoadingScreen, assigned to the LoadingScreen image:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class LoadingScreen : MonoBehaviour {

 Slider loadingSlider;
 CanvasGroup cg;

 // Use this for initialization
 void Start () {

  loadingSlider = GetComponentInChildren < Slider> ();
  cg = GetComponent<CanvasGroup> ();
  cg.alpha = 0;
 
 }
 
 public void AssignValue(float v)
 {
  loadingSlider.value = v;
 }

 public void Activate()
 {
  cg.alpha = 1;
 }
}

Nothing special, after getting all my references, I declare 2 methods, one that assign a float value to the slider and the other one that simply shows the whole canvas by raising the alpha value of the canvas group to 1.

Now, the other script, called LoadScene. This script is assigned to the button and its purpose is to load the next scene. Obviously, this is just our case, the loading screen could be activated by any other object that is required to load a scene.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class LoadScene : MonoBehaviour, IPointerUpHandler {
 

 public LoadingScreen loadingScreen;

 public int sceneToload;

 AsyncOperation ao = null;

 void IPointerUpHandler.OnPointerUp (PointerEventData eventData)
 {
  StartCoroutine (loadScene (sceneToload));
 }

 

 IEnumerator loadScene(int s)
 {

  ao = SceneManager.LoadSceneAsync (s);

  loadingScreen.Activate ();
  while (!ao.isDone) {
   
   loadingScreen.AssignValue (ao.progress);
   yield return null;
  }
 }



}

For this script we need to add the namespace UnityEngine.EventSystems. To add functionality to the button, I use the interface IPointerUpHandler, as you can see from the script above. This will require to override the method you see declared on line 10, which in our case will start the coroutine on line 17.

Also, we need the UnityEngine.SceneManagement so we can use the code for loading scenes as the old Application,Load(...) is now deprecated.

This coroutine accepts an integer value that represents the scene to load. Then, we assign the previously declared AsyncOperation parameter ao  to the object obtained by the static method LoadSceneAsync(...) of the SceneManagement class.

At this point we can activate the loading screen, which was given as a public value to this script so we can drag it in directly from the inspector.

The while loop is where everything happens: we check the the ao, which is our async operation, has not finished, and for each cycle we get the progress value with ao.progress, which is passed to the slider that will move accordingly.

No comments:

Post a Comment