アンリアる! C++入門編 ~対話形式で学ぶUnreal Engine~
BOOTHでUnreal Engine C++入門書を販売していますUnreal Engine上でC++を使って開発するために必要となる基礎知識を一冊の本にまとめた本です。 対話形式によるわかりやすい説明を目指しました。無料の試し読みも可能ですので、ぜひ読んでみてください!
[UE4] How to Create a Loading Animation

It is common to use "Open Level" when you load different levels in Unreal Engine.
But "Open Level" is a synchronous process, and it makes the game freeze while loading a level.
For this reason, it is common to load levels asynchronously while displaying a loading animation.

This article explains how to load a level asynchronously in the Unreal Engine while displaying the loading animation.

Loading a level using OpenLevel

First, we will show how to load another level without displaying a loading animation.
Generally, it is common to use "Open Level" when you load a level synchronously in Unreal Engine.

Open Level

"Open Level" makes the game process (including the drawing process) stop until the specified level is loaded.
This makes the game freeze.
If the screen fades out gradually before "Open Level" is executed, the game looks much more natural.
But if it remains dark for a long time, the player is anxious whether the game is running correctly or frozen.
For this reason, loading another level asynchronously is a basic strategy while displaying loading animations or game tips.

Loading a level with a loading animation

Loading a new level asynchronously with a loading animation on the Unreal Engine requires tricky processes.
To realize the loading levels asynchronously, we will shows a demo that loads a level with a loading animation.

Demo Specifications

The flow of the demo of loading levels with a loading animation is as follows.

  1. At the beginning of the game (after pressing the Play button), the first Level (Level A) is loaded first.
  2. When the B button is pressed, the loading animation is displayed and the second Level (Level B) is loaded simultaneously.
  • When Level B is loaded, "Level B Loaded" is displayed on the screen.
  • When Level B is loaded, the loading animation and Level A are disappeared.
  1. When Level A is loaded, the loading animation is appeared.
  • When Level A is loaded, "Level A Loaded" is displayed on the screen.
  • When Level A is loaded, the loading animation and Level A are disappeared.

From here, we will explain how to realize this process.

Level Structure

To realize the asynchronous processing of levels, create a level loaded asynchronously and a level that manages the levels.
The management level loads the levels asynchronously.
In the Unreal Engine, a Persistent Level should be a management level, and a sub level should be loaded asynchronously by it.
Since a Persistent Level is a unique level in the game and can hold multiple sub levels, it is suitable to be used as a level to manage its sub levels.

  • "Open Level" loads this Persistent Level. This indicates that the Persistent Level can only be read synchronously.

Level and Sub Level

To realize the demonstration, we will consider the following level structure.
Create a level with the name displayed in the Level Name.
Note that the loading animation is also managed as the sub level by the Persistent Level in order to dynamically show/hide the loading animation without switching the Persistent Level.

Level Name
Persistent Level L_LevelGroup
Sub Level (Level A) L_LevelA
Sub Level (Level B) L_LevelB
Sub Level (Loading Animation) L_LoadingAnimation

Once you create these levels, then realize the above level structure.
First, open the Level tab with the Level "L_LevelGroup" opened.
Add three sub levels and turn off the visibility of all then.
This makes these sub levels unloaded when the Persistent Level is loaded.

Level Structure

Level Loading Process

The process of loading sub levels (L_LevelA and L_LevelB) asynchronously while displaying the loading animation is as follows.

  1. Load L_LoadingAnimation asynchronously using "Load Stream Level (by Name)".
  2. Check "Make Visible After Load" in "Load Stream Level (by Name)" to display a loading animation after L_LoadingAnimation has loaded.
  3. Load the level (L_LevelA or L_LevelB) asynchronously using "Load Stream Level (by Name)".
  4. Check "Make Visible After Load" in "Load Stream Level (by Name)" to display the loaded level.
  5. Delete the old level (L_LevelB if L_LevelA is loaded) and L_LoadingAnimation using "Unload Stream Level (by Name)".

Level Loading Process

By displaying a loading animation in the process of loading L_LevelA and L_LevelB, it is possible to prevent the game to be frozen.
A similar method can be used to display game tips instead of the loading animation.
However, the old level will continue to exist while the new level is being loaded.
It should be careful for the old level’s process (Disable the player’s input if necessary) not to cause the bugs.

Implement the Level Loading Process

We will show the process of the implementation by Blueprint.
The implementation flow is as follows.

  1. Create UI (W_LoadingAnimation) for the loading animation.
  2. Create a Blueprint Interface (BP_LoadingInterface) for communication between L_LevelGroup and L_LoadingAnimation.
  3. Add loading process of the loadtion animation to the Blueprint of L_LevelGroup.
  4. Add loading process of L_LevelA or L_LevelB to the Blueprint of L_LoadingAnimation.
  5. Add a process to output a message after loading is completed to the Blueprint ofL_LevelA and L_LevelB.
  6. Delete old levels and loading animations.

To understand the overview, we will show the file structure for the demo as follows.

File Structure

From here, we will explain each step will in detail.

1. Create UI for the Loading Animation

Create UI for the loading animation that will be displayed while the level is being loaded.
For this demo, we will create an asset called W_LoadingAnimation derived from the User Widget.
The W_LoadingAnimation displays the text "Now Loading …" at the centered, and adds an animation that blinks the text at one-second intervals.
Open the Blueprint editor and add a Play Animation node.
Then connects to the Event Construct.
Specify the animation you created and set "Num Loops to Play" to 0.
This makes the animation loop indefinitely.

W_LoadingAnimation (UI)

W_LoadingAnimation (Blueprint)

2. Create a Blueprint Interface

L_LevelGroup switches the level to be loaded according to the input button.
For this purpose, we implement the common process in L_LoadingAnimation.
L_LevelGroup and L_LoadingAnimation are connected by Blueprint Interface.
The Blueprint Interface has an argument for passing the level name.

  • We have another method to implement a common process as a function in L_LevelGroup. But this is not possible because the common process includes asynchronous processes. To solve this problem, we implement the common process in L_LoadingAnimation and call from L_LevelGroup via Blueprint Interface.

The asset name of the Blueprint Interface is "BP_LoadingInterface".
Add the function "LoadingAnimationLoaded" with two inputs.

Input Name Type Meaning
NextLevel Name Level to load
CurrentLevel Name Current Level

BP_LoadingInterface

3. Add Loading Process of Loading Animation

Add a process to load the loading animation.
In this demonstration, the loading animation is created as the sub level L_LoadingAnimation.

The sub level is loaded by "Load Stream Level (by Name)".
The argument Level Name is the name of the level to be loaded (In this case, L_LoadingAnimation).
As indicated by the clock symbol in the upper right corner of the node, "Load Stream Level (by Name)" is executed asynchronously.

When "Load Stream Level (by Name)" is executed, the loading of L_LoadingAnimation is complete.
When loading is completed, issue the message "Loading Animation Loaded" created in the Blueprint Interface to L_LoadingAnimation.
Specify L_LevelA to the input NextLevel when key A is pressed, and specify L_LevelB when key B is pressed.
Specify the current level to the input CurrentLevel.

L_LevelGroup (Blueprint for key A and key B)

When the game starts (when the BeginPlay event is issued), L_LevelA is loaded.
We connects to Begin Play node about the same process when key A is processed.

L_LevelGroup (Blueprint of BeginPlay)

Next, implement the process executed for the event "Loading Animation Loaded" in L_LoadingAnimation.
UI of the loading animation W_LoadingAnimation, is displayed by using "Create Widget" and "Add to Viewport".

L_LoadingAnimation (Blueprint 1)

4. Add the Level Loading Process

After the loading animation is loaded, loads the level (L_LevelA or L_LevelB).
This is accomplished by "Load Stream Level (by Name)" in the same way as loading the loading animation.
The argument Level Name specifies the level to be loaded.
Here, we use the input Next Level of "Loading Animation Loaded".

The level loading can be a very time-consuming process depending on the amount of data contained in the level.
When you load a level with the almost initial state, the execution time is trivial.
It makes us difficult to see the effect of asynchronous loading.
Therefore, we will add a "Delay" node after the "Load Stream Level (by Name)".
This takes the loading process for more than 3 seconds at least.

L_LoadingAnimation (Blueprint 2)

5. Add a Process to Output a Message after Loading is Completed

After the loading process is completed, output a message to shows that the loading is complete.
In this demonstration, we implement by using "Remote Event".
The event names are as follows.

L_LoadingAnimation (Blueprint 3)

Event Name Meaning
L_LevelALoaded L_LevelA has loaded
L_LevelBLoaded L_LevelB has loaded

Next, open the Blueprint for L_LevelA.
Create a Custom Event "L_LevelALoaded.
Connect a "Print String" node to "L_LevelALoaded" to output the message "L_LevelA Loaded" when the event is received.

L_LevelA

Similarly, create a custom event in Blueprint for L_LevelB.

L_LevelB

6. Delete Old Levels and Loading Animations

Return to the Blueprint for L_LoadingAnimation.
After sending the event with "Remote Event", delete the old level and loading animation.
To delete the old level first, specify the input Current Level of "Loading Animation Loaded" to "Unload Stream Level (by Name)".

Once the level is deleted, delete the loading animation.
Use "Reomve from Parent" to delete the loading animation W_LoadingAnimation from L_LoadingAnimation.
Finally, specify L_LoadingAnimation to "Unload Stream Level (by Name)" to remove the loading animation.

L_LoadingAnimation (Blueprint 4)

Run

Let’s try loading the level with the loading animation.

When the play button is pressed with L_LevelGroup opened, the loading animation "Now Loding …" is displayed for a while.
Then, "Now Loding …" is displayed and the loading animation disappears.
Pressing key B displays "Level B Loaded" after the loading animation appears.
In the same way, pressing key A displays "Level A Loaded" after the loading animation appears.
You will see that a loading animation is displayed while the level is loading.

Loading Animation Demo

  • Because key input is not disabled during the loading, pressing a key during the loading may not work properly. It is necessary to disable key input during the loading process as you can see.

Summary

We have explained how to load a level with the loading animation.
Although the procedure for asynchronous level loading is complicated, it is worth to implement for the UI improvement.
The asynchronous level loading described in this article is also used for open world games.

Try to refer to this article when you implement the asynchronous leel loading in the Unreal Engine.