# Scene System

## How it works

**\_Loader** scene is Application enter point and holder of all persistant singletons, shows custom splash screen.\
for example GameResources (that contains information about skins and configs) can be here.\ <mark style="color:yellow;">**But remember to use DontDestroyOnLoad(gameObject) so they will not disappear after scene load!**</mark>

### How to add new scenes

Simply create new scenes in project, add it to build settings, but leave **\_Loader** at first as possble index = 0 (some SDKs requires to replace scenes on top of all project scenes -> then you need to leave **\_Loader** after SDK scenes).

## API

{% code lineNumbers="true" %}

```csharp
public static SceneSystem Instance;

public static Scene SingleActiveScene;
public static Scene SinglePreviousScene;

/// on/off logs from SceneSystem
public bool verboseLogs;

/// UnityAction, invokes when scene is full ready to be used
/// You can use it to enable AI or activate play timer and etc.
/// If loadScreen was - event executed on start of loadScreen disappear.
/// In all, this event invokes only when <see cref="Initialization"/> completed (if no initialization running - instantly as soon as scene loads)
public static UnityEvent OnSceneFullReady = new();
public static UnityEvent OnSingleModeSceneStartLoading = new();

// Use LoadScene to change scenes (with or without load screen transition)
public void LoadScene(); // and it's overrides
public void AdditiveScenesChange(); // and it's overrides

/// Iterates through scenes in hierarchy and sets as active if found
public void SetActiveScene(string withName);
public void ReloadActiveScene(bool async = true);
```

{% endcode %}

### How to switch scene

Use SceneSystem.cs API. Scene system is [MonoSingleton](https://reddycat.gitbook.io/base-project-cube-doc/fundamentals/singletons).

Simply call LoadScene`(..)` that has overrides (immediate, with loadScreen):

```csharp
// immediate load
SceneSystem.Instance.LoadSceneSwitch("MainMenu");

// load with loadScreen
SceneSystem.Instance.LoadSceneSwitch("MainMenu", LoadScreens.FadeInOut);
```

\
If you want to load scenes additively -> call `AdditiveScenesChange(..)`:

<pre class="language-csharp"><code class="lang-csharp"><strong>// immediate load
</strong><strong>SceneSystem.Instance.AdditiveScenesChange(unloadScenes: null, 
</strong><strong>            new string[] { "scene_1", "scene_2" });
</strong>
// load with loadScreen
SceneSystem.Instance.AdditiveScenesChange(unloadScenes: null, 
            new string[] { "scene_1", "scene_2" }, 
            onLoadScreenShown: () => Debug.Log("+"), 
            LoadScreens.FadeInOut);

// unload scenes only
SceneSystem.Instance.AdditiveScenesChange(
            unloadScenes: new string[] { "scene_1", "scene_2" }, 
            loadScenes: null);
</code></pre>

{% hint style="success" %}
SceneSystem works with [**Initialization**](https://reddycat.gitbook.io/base-project-cube-doc/fundamentals/singletons/scene-system/initialization) + [**LoadScreens**](https://reddycat.gitbook.io/base-project-cube-doc/fundamentals/singletons/load-screen-manager). If you load scene with loadScreen and that scene will Initialize for 1 sec then load screen will disappear after 1 sec when scene loaded.
{% endhint %}

{% hint style="info" %}
Learn more information how to implement custom load screens [**here**](https://reddycat.gitbook.io/base-project-cube-doc/fundamentals/singletons/load-screen-manager/implementing-custom-load-screens).
{% endhint %}

You can find more examples in **Assets\\\_Examples\Scene System\\**
