Class ScyllaSceneManager
Built-in Core subsystem for scene management. Keeps the framework and its modules alive across scene loads and provides managed asynchronous scene loading with progress reporting, activation gating, and scene lifecycle events.
Inherited Members
Namespace: Scylla.Core.Scenes
Assembly: ScyllaCore.dll
Syntax
public sealed class ScyllaSceneManager
Remarks
Like ScyllaTime, this is a plain C# singleton
initialized by ScyllaBootstrap during the one-shot framework setup, not a
Scylla module. Access it via Instance after the bootstrap has
awakened; the instance survives scene loads because it lives in static state.
Framework persistence: When
PersistFrameworkAcrossScenes is enabled
(the default, also used when no configuration asset exists),
Initialize(ScyllaSceneConfiguration, GameObject) moves the bootstrap GameObject, and with it every module
child, into Unity's DontDestroyOnLoad scene. The framework hierarchy then survives
every scene load in every load mode, including raw
SceneManager.LoadScene calls made outside this subsystem. Bootstraps found
in scenes loaded afterwards are removed by ScyllaBootstrap's
duplicate detection in favor of the persistent instance.
Managed loading: LoadSceneAsync(string, ScyllaSceneLoadOptions),
UnloadSceneAsync(string), and ReloadActiveSceneAsync()
return a SceneLoadOperation handle exposing progress, an activation
gate for loading screens, and completion via Awaitable or callback. SEX
events are published around every transition (will-load, progress, loaded,
will-unload, unloaded, active-scene-changed).
/* Gated load driving a loading screen. */
var op = ScyllaSceneManager.Instance.LoadSceneAsync("OpenWorld",
ScyllaSceneLoadOptions.Default.WithManualActivation());
while (op.State == SceneLoadState.Loading)
{
loadingBar.Value = op.Progress;
await Awaitable.NextFrameAsync();
}
await loadingScreen.PlayOutro();
op.AllowActivation = true;
await op.Awaitable;
Concurrency rules (fail-fast): a single-mode load requires that no other operations are in flight; additive loads and unloads of distinct scenes may run concurrently; starting an operation on a scene that already has one in flight throws.
Transition hygiene: managed operations that destroy scene objects (single-mode loads, reloads, unloads, and the synchronous wrapper) automatically run a config-gated cleanup pipeline before the Unity operation starts: kill all tweens, clear the timescale-modifier stack, and prune destroyed event-bus subscribers. Additive loads skip hygiene unless a per-call ForceOn is set; every step can also be forced off per call via ScyllaSceneLoadOptions.
Transition tasks: game code can register awaitable hooks that run sequentially inside asynchronous load operations: RegisterPreLoadTask(Func<Awaitable>) hooks run after the will-events and before hygiene (fade-outs, autosaves), RegisterPostLoadTask(Func<Awaitable>) hooks run after activation and before the operation completes (fade-ins, spawning). Exceptions in a task are logged and isolated; the pipeline continues. The synchronous LoadScene(string, ScyllaSceneLoadOptions) wrapper does not run transition tasks.
A game that never loads scenes pays no runtime cost for this subsystem: it has no update loop while idle, and the asynchronous load driver is spawned lazily on the first managed operation and disables itself between operations.
Properties
CurrentOperation
Gets the most recently started operation that is still in flight, or null
when idle. With concurrent additive operations this is the newest one; use the
handles returned by the load methods to track specific operations.
Declaration
public SceneLoadOperation CurrentOperation { get; }
Property Value
| Type | Description |
|---|---|
| SceneLoadOperation |
Instance
Gets the active singleton instance of the scene management service.
Declaration
public static ScyllaSceneManager Instance { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaSceneManager |
IsLoading
Gets whether any managed scene operation is currently in flight, including a pending synchronous load.
Declaration
public bool IsLoading { get; }
Property Value
| Type | Description |
|---|---|
| bool |
PersistenceEnabled
Gets whether framework persistence is active, i.e. the bootstrap hierarchy was moved to DontDestroyOnLoad during initialization and survives scene loads.
Declaration
public bool PersistenceEnabled { get; }
Property Value
| Type | Description |
|---|---|
| bool |
|
Methods
LoadAddressableSceneAsync(string, ScyllaSceneLoadOptions)
Starts a managed asynchronous load of an Addressables scene by address key. Behaves exactly like LoadSceneAsync(string, ScyllaSceneLoadOptions) (hygiene, events, activation gate, minimum duration, transition tasks) but routes through the Addressables system, so the scene may be downloaded on demand.
Declaration
public SceneLoadOperation LoadAddressableSceneAsync(string address, ScyllaSceneLoadOptions options = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | address | The Addressables address key of the scene. Must be non-empty. |
| ScyllaSceneLoadOptions | options | Per-call options; |
Returns
| Type | Description |
|---|---|
| SceneLoadOperation | The operation handle exposing progress, the activation gate, and completion. |
Remarks
Until the scene resolves, the operation's SceneName carries the address
(which is also the identity used by the concurrency guards); after completion
Scene is the loaded scene. An invalid address or missing bundle fails
asynchronously: the operation reaches Failed with
the Addressables error in Error. Unloading an addressable-loaded scene
goes through the regular UnloadSceneAsync(Scene, ScyllaSceneLoadOptions);
the manager routes it through the Addressables unload path automatically.
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | The address is null or empty. |
| InvalidOperationException | Called outside play mode, or the concurrency rules are violated. |
LoadAddressableSceneAsync(AssetReference, ScyllaSceneLoadOptions)
Starts a managed asynchronous load of an Addressables scene via an UnityEngine.AddressableAssets.AssetReference. See LoadAddressableSceneAsync(string, ScyllaSceneLoadOptions) for the shared behavior.
Declaration
public SceneLoadOperation LoadAddressableSceneAsync(AssetReference sceneReference, ScyllaSceneLoadOptions options = default)
Parameters
| Type | Name | Description |
|---|---|---|
| AssetReference | sceneReference | The scene asset reference. Must be non-null. |
| ScyllaSceneLoadOptions | options | Per-call options; |
Returns
| Type | Description |
|---|---|
| SceneLoadOperation | The operation handle exposing progress, the activation gate, and completion. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | The reference is null. |
| ArgumentException | The reference has no valid runtime key (misconfigured). |
| InvalidOperationException | Called outside play mode, or the concurrency rules are violated. |
LoadScene(string, ScyllaSceneLoadOptions)
Synchronously loads the scene with the given name, publishing the same will-unload and will-load events as the asynchronous API. Completion events (unloaded, loaded, active-scene-changed) are published when Unity reports the scene loaded, which for synchronous loads is at the start of the next frame.
Declaration
public void LoadScene(string sceneName, ScyllaSceneLoadOptions options = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | sceneName | The name of the scene to load. Must be non-empty and included in the build. |
| ScyllaSceneLoadOptions | options | Per-call options. Only |
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | The scene name is null or empty, or the scene cannot be loaded. |
| InvalidOperationException | Called outside play mode, or the concurrency rules are violated. |
LoadSceneAsync(int, ScyllaSceneLoadOptions)
Starts a managed asynchronous load of the scene at the given build index.
Declaration
public SceneLoadOperation LoadSceneAsync(int buildIndex, ScyllaSceneLoadOptions options = default)
Parameters
| Type | Name | Description |
|---|---|---|
| int | buildIndex | The build index of the scene to load. Must be non-negative. |
| ScyllaSceneLoadOptions | options | Per-call options; |
Returns
| Type | Description |
|---|---|
| SceneLoadOperation | The operation handle exposing progress, the activation gate, and completion. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | The build index is negative. |
| ArgumentException | The scene cannot be loaded (invalid build index). |
| InvalidOperationException | Called outside play mode, or the concurrency rules are violated (see the class remarks). |
LoadSceneAsync(string, ScyllaSceneLoadOptions)
Starts a managed asynchronous load of the scene with the given name.
Declaration
public SceneLoadOperation LoadSceneAsync(string sceneName, ScyllaSceneLoadOptions options = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | sceneName | The name of the scene to load. Must be non-empty and included in the build. |
| ScyllaSceneLoadOptions | options | Per-call options; |
Returns
| Type | Description |
|---|---|
| SceneLoadOperation | The operation handle exposing progress, the activation gate, and completion. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | The scene name is null or empty, or the scene cannot be loaded (not included in the build settings). |
| InvalidOperationException | Called outside play mode, or the concurrency rules are violated (see the class remarks). |
RegisterPostLoadTask(Func<Awaitable>)
Registers an awaitable factory that runs after scene activation and before a managed asynchronous load operation completes (fade-ins, spawning). Tasks run sequentially in registration order; exceptions are logged and isolated.
Declaration
public void RegisterPostLoadTask(Func<Awaitable> task)
Parameters
| Type | Name | Description |
|---|---|---|
| Func<Awaitable> | task | The awaitable factory to register. Must be non-null. |
Remarks
Tasks are awaited on the main thread. A task may hop to a background thread (for
example Awaitable.BackgroundThreadAsync) for its own work, but the subsystem
restores the main thread before continuing regardless, so the rest of the load runs
correctly even if a task forgets to switch back. Each task's returned awaitable must
eventually complete: a task that never completes stalls the operation, which stays in
flight and blocks subsequent single-mode loads.
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | The task is null. |
RegisterPreLoadTask(Func<Awaitable>)
Registers an awaitable factory that runs before the hygiene pipeline of every managed asynchronous load (fade-outs, autosaves). Tasks run sequentially in registration order; exceptions are logged and isolated.
Declaration
public void RegisterPreLoadTask(Func<Awaitable> task)
Parameters
| Type | Name | Description |
|---|---|---|
| Func<Awaitable> | task | The awaitable factory to register. Must be non-null. |
Remarks
Tasks are awaited on the main thread. A task may hop to a background thread (for
example Awaitable.BackgroundThreadAsync) for its own work, but the subsystem
restores the main thread before continuing regardless, so the rest of the load runs
correctly even if a task forgets to switch back. Each task's returned awaitable must
eventually complete: a task that never completes stalls the operation, which stays in
flight and blocks subsequent single-mode loads.
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | The task is null. |
ReloadActiveSceneAsync()
Reloads the currently active scene in single mode with default options. Sugar for
LoadSceneAsync(SceneManager.GetActiveScene().name); the standard restart
path for game-over screens.
Declaration
public SceneLoadOperation ReloadActiveSceneAsync()
Returns
| Type | Description |
|---|---|
| SceneLoadOperation | The operation handle for the reload. |
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Called outside play mode, or other operations are in flight. |
UnloadSceneAsync(string, ScyllaSceneLoadOptions)
Starts a managed asynchronous unload of the scene with the given name. Unloads run
the transition hygiene pipeline by default; use the hygiene overrides on
options to adjust per call.
Declaration
public SceneLoadOperation UnloadSceneAsync(string sceneName, ScyllaSceneLoadOptions options = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | sceneName | The name of a currently loaded scene. |
| ScyllaSceneLoadOptions | options | Per-call options. Only the hygiene overrides are honored for unloads; the load mode, activation, and duration settings do not apply. |
Returns
| Type | Description |
|---|---|
| SceneLoadOperation | The operation handle; its |
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | The scene name is null or empty, or no loaded scene has that name. |
| InvalidOperationException | Called outside play mode, the scene is the only loaded scene, or the concurrency rules are violated. |
UnloadSceneAsync(Scene, ScyllaSceneLoadOptions)
Starts a managed asynchronous unload of the given scene. Unloads run the transition
hygiene pipeline by default; use the hygiene overrides on options
to adjust per call.
Declaration
public SceneLoadOperation UnloadSceneAsync(Scene scene, ScyllaSceneLoadOptions options = default)
Parameters
| Type | Name | Description |
|---|---|---|
| Scene | scene | A currently loaded scene. |
| ScyllaSceneLoadOptions | options | Per-call options. Only the hygiene overrides are honored for unloads; the load mode, activation, and duration settings do not apply. |
Returns
| Type | Description |
|---|---|
| SceneLoadOperation | The operation handle; its |
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | The scene handle is invalid or the scene is not loaded. |
| InvalidOperationException | Called outside play mode, the scene is the only loaded scene, or the concurrency rules are violated. |
UnregisterPostLoadTask(Func<Awaitable>)
Unregisters a previously registered post-load task. Safe to call for tasks that were never registered.
Declaration
public void UnregisterPostLoadTask(Func<Awaitable> task)
Parameters
| Type | Name | Description |
|---|---|---|
| Func<Awaitable> | task | The awaitable factory to remove. |
UnregisterPreLoadTask(Func<Awaitable>)
Unregisters a previously registered pre-load task. Safe to call for tasks that were never registered.
Declaration
public void UnregisterPreLoadTask(Func<Awaitable> task)
Parameters
| Type | Name | Description |
|---|---|---|
| Func<Awaitable> | task | The awaitable factory to remove. |