You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
_Collection of tools to improve scene management and transitions in Unity._
8
+
_A package that standardizes the scene loading process among many different possibilities, including support for Coroutines, C# Tasks, UniTask and Addressables._
9
9
10
10
Installation
11
11
---
@@ -28,29 +28,277 @@ You should add this to your `manifest.json` under the `Packages` folder on the r
28
28
Overview
29
29
---
30
30
31
-
Loading scenes in Unity is very simple, but developing games sometimes require more flexible implementations. This package has two main focuses:
32
-
33
-
1. Cover the most common uses of Scene Loading
34
-
2. Provide `awaitable` implementations
35
-
31
+
Loading scenes in Unity is very simple, but developing games sometimes require more flexible implementations. This package aims to simplify common use cases for scene loading.
36
32
Additionally, it offers support for [Unity Addressables](https://docs.unity3d.com/Manual/com.unity.addressables.html) and for [UniTask](https://github.com/Cysharp/UniTask) with no additional setup required.
37
33
38
-
The paradigm for Scene Loading relies in the following actions:
39
-
***Load**: loads a new scene on top of the current scene structure.
40
-
***Unload**: unloads one of the scenes in the scene structure.
41
-
***Switch**: replaces the current active scene with a new one (executes both unload and load operations).
42
-
***Transition**: switches to another scene but with an intermediate "loading scene" in between.
34
+
Aside from the ordinary **Load** and **Unload** actions, the Scene Loading tools introduce the **Transition** as a new standard to control transitions between scenes with an optional intermediate "loading scene" in between.
43
35
44
-
Keep that in mind when using the scene loader utilities.
36
+
:information_source: You don't need to understand what **Addressables** or **UniTask** do in order to use this package. There are scene loaders that only rely on basic Unity Engine functionalities.
45
37
46
38
Usage
47
39
---
48
40
49
-
There are **four** scene loaders that you can use, depending on your project necessities:
50
-
1.`AsyncSceneLoader`: simple scene loader with `awaitable` instructions.
51
-
2.`UniTaskSceneLoader`: the `AsyncSceneLoader` with `UniTask` instead of `Task`.
52
-
3.`AddressableAsyncSceneLoader`: a scene loader that handles Addressable scenes with `awaitable` instructions.
53
-
4.`AddressableUniTaskSceneLoader`: the `AddressableSceneLoader` with `UniTask` instead of `Task`.
41
+
Loading scenes with this package implies that the scenes **will always be loaded as Additive**. That is simply because there is no advantage in loading scenes in the **Single** load scene mode when you expect to work with multiple scenes. There are **six** scene loaders that you can use, depending on your project necessities:
42
+
1.`SceneLoaderAsync`: simple scene loader with `awaitable` instructions.
43
+
2.`SceneLoaderCoroutine`: simple scene loader with `Coroutine` instructions.
44
+
3.`SceneLoaderUniTask`: the `SceneLoaderAsync` with `UniTask` instead of `Task`.
45
+
4.`AddressableSceneLoaderAsync`: a scene loader that handles Addressable scenes with `awaitable` instructions.
46
+
5.`AddressableSceneLoaderCoroutine`: a scene loader that handles Addressable scenes with `Coroutine` instructions.
47
+
6.`AddressableSceneLoaderUniTask`: the `AddressableSceneLoaderAsync` with `UniTask` instead of `Task`.
48
+
49
+
Before we go into each one, let's understand how we got there. There are some core differences between loading scenes with the `SceneManager` and via Addressables.
50
+
51
+
- | SceneManager | Addressables
52
+
--- | --- | ---
53
+
Scene Reference | Build Index, Scene Name or Path | Asset Reference, Address Runtime Key
54
+
Active Scene | Managed through `SceneManager` | None
55
+
Loaded Scenes | Managed through `SceneManager` | No high level API available
56
+
57
+
Due to those differences, the Addressable scene loaders had to be split into their own logic. However, in order to simplify the usability, even though the Addressable does not work entirely with the `SceneManager`, the way you interact with its scene loaders is very similar to how you would interact with the others.
58
+
59
+
### The Scene Loader
60
+
61
+
The most basic usability you'll get from a scene loader is to **Load** a scene, **Unload** it, or **Transition** to another scene. That's what the `ISceneLoader` interface will define:
Observe that instead of defining `int` or `string` parameters for the scene's build index or name, it defines the `ILoadSceneInfo` interface instead. That is just a way of standardizing the scene information that we'll be working with, instead of creating multiple methods, each with their own implementation.
75
+
76
+
The `ILoadSceneInfo` defines:
77
+
78
+
```cs
79
+
publicinterfaceILoadSceneInfo
80
+
{
81
+
AsyncOperationUnloadSceneAsync();
82
+
83
+
AsyncOperationLoadSceneAsync();
84
+
85
+
SceneGetScene();
86
+
}
87
+
```
88
+
89
+
Then you'll be able to use whatever fits your use case: the `LoadSceneInfoIndex` or the `LoadSceneInfoName` which you can create just as you would expect:
90
+
91
+
```cs
92
+
// Create an ILoadSceneInfo by the scene's build index:
As a final example, let's suppose you're currently at the **"Main Menu"** scene and you want to transition to the **"Level 1"** scene with the **"Loading Tips"** loading scene. You could for example:
This would trigger the scene transition by loading the **"Loading Tips"** scene first, and then starting to load the **"Level 1"** scene while showing its load progress in the loading scene. Then, when the **"Level 1"** scene is done loading, the **"Loading Tips"** scene will get unloaded and the transition will be complete.
106
+
107
+
Now, what if you wanted to _await_ this call?
108
+
109
+
### Awaitable Scene Loaders
110
+
111
+
You have three options of _awaitable_ scene loaders to choose: **Coroutine**, **C# Task (Async)** and **UniTask**. Coroutine is not C# awaitable, but it works similarly if you `yield return` it inside another Coroutine. If you want to use **UniTask**, make sure you [install its package](https://github.com/Cysharp/UniTask#upm-package) in your project.
112
+
113
+
Since each implementation changes what you'll get as the return types, they all have their own interfaces:
In the end however, they all also implement `ISceneLoader`, so even though you'll only use the basic `ISceneLoader` methods, you can still take advantage of the `UniTask` implementation, for example. Otherwise, if you're going to await the operation, then you can choose the system that fits you best.
145
+
146
+
### Addressable Scene Loading
147
+
148
+
The Addressable Scene Loading introduces a few more concepts in order to keep the simplicity of the regular scene loading process. Take for example the `IAddressableSceneLoader` interface:
You can see that it has two main differences from the `ISceneLoader`: the presence of the `IAddressableSceneManager` and the different parameter types. Other than that, the usability is exactly the same.
164
+
165
+
Instead of a single `ILoadSceneInfo` parameter type, the Addressable implementation has two different interfaces: the `IAddressableLoadSceneReference` and the `IAddressableLoadSceneInfo`. This is due to nature of the **Load** and **Unload** scene operations of the Addressables System, in which you need different parameters for each operation.
166
+
167
+
Take a look for example in the definition of the `IAddressableLoadSceneReference`:
It only defines the **Load** operation that returns an `AsyncOperationHandle<SceneInstance>`. To create an object that defines this interface, you can either use the scene's `AssetReference` or its runtime key, which is how you normally reference assets with Addressables.
177
+
178
+
```cs
179
+
// Create an IAddressableLoadSceneReference by the scene's AssetReference:
Although very similar to the **Load** operation, it's important to note here that you'll need different scene information in order to create an object that implements this method. You'll need either the `AsyncOperationHandle<SceneInstance>` that was used to load the scene, or the `SceneInstance` itself, or in last case the loaded scene name.
196
+
197
+
```cs
198
+
// Create an IAddressableLoadSceneInfo by the scene's AsyncOperationHandle<SceneInstance>:
As you could see, both `IAddressableLoadSceneReference` and `IAddressableLoadSceneInfo` require the `IAddressableSceneManager` as a parameter of their methods.
209
+
210
+
### The Addressable Scene Manager
211
+
212
+
Loading scenes through Addressables does not exactly pass through the `SceneManager`. It does fire callbacks for loading and unloading scenes, but there's no way to get the active scene or to get any of the loaded scenes, if they have been loaded through the Addressables System. For that reason, the `IAddressableSceneManager` defines a standard for an Addressable Scene Manager that keeps track of the loaded scenes and of an active scene as well, just like you'd expect with the regular `SceneManager`.
213
+
214
+
It's only going to be used internally by the scene loaders, but take a look at its definition:
Not only it provides methods for loading and unloading scenes with the many ways to reference them, but it also keeps track of the loaded scenes and manages the current active scene. The `IAddressableLoadSceneReference` and `IAddressableLoadSceneInfo` implementations require the scene manager for calling these methods, just like in the non-addressable implementations, they also do it but statically via the `SceneManager`.
236
+
237
+
Now we can load addressable scenes, but what about _awaiting_ them too?
238
+
239
+
### Awaitable Addressables
240
+
241
+
The Addressables System has much better support for awaiting operations than the other Unity Engine systems. While it can be easier to implement, we still need to adapt it to work with the defined standards in the previous topics. So, not so different from the non-addressable implementation, we have the three options for awaitable scene loaders:
Just like before, they also implement the `IAddressableSceneLoader` so you can use what you prefer.
273
+
274
+
### Why so many interfaces?
275
+
276
+
The idea behind the interfaces is first to decouple things and second to allow you to build your own systems if you require something very different from the provided content. Sometimes projects require very specific implementations, and instead of making the system extremely complex and detailed, I'd rather have it broken into many different pieces that you can replace to fit with whatever works best in each use case.
277
+
278
+
I am always open to suggestions, so please if you have any, don't hesistate to share!
279
+
280
+
Samples
281
+
---
282
+
283
+
This package offers samples with each of the scene loaders for you to use as a starting point. To use them, simply import the desired sample through the Package Manager.
284
+
285
+
### For non-Addressable scene loaders:
286
+
287
+
Make sure you add all scenes to the build settings with the following indexes:
288
+
289
+
0. SceneA
290
+
1. SceneB
291
+
2. SceneLoading
292
+
3. SceneC_add
293
+
4. SceneD_add
294
+
295
+
You can try out the sample by loading either the SceneA or SceneB and hitting play in the Unity Editor.
296
+
297
+
### For Addressable scene loaders:
298
+
299
+
Make sure you mark all scenes as addressables and simplify their names in the Addressable Groups window. To test, open up the **Bootstrap** scene and hit play.
300
+
301
+
Check if your Addressables Play Mode Script is `Use Asset Database`, otherwise you may be required to build the Addressable groups.
0 commit comments