Skip to main content
Version: 5.x
Supported on
Snapchat
Spectacles
Camera Kit

Scene Manager

The Scene Manager is a custom component that simplifies organizing your Lens into distinct scenes. This component provides essential functions for scene management, including loadSceneSync, loadSceneAsync, unloadScene, and unloadSceneByName. It's a crucial tool for projects requiring multiple scenes, such as multi-level games or multi-layered Lenses.

This guide covers the Scene Manager's core functionalities and their usage. With the Scene Manager, you can:

  • Organize your Lens into logical, manageable scenes.
  • Load and unload scenes efficiently using simple functions.
  • Achieve smooth scene transitions with asynchronous loading.
  • Release resources by unloading scenes by name.
  • Develop multi-scene experiences like games and interactive stories.

The Scene Manager enables the creation of complex and modular Lens Studio projects. This guide will demonstrate how to effectively use this component in your Lenses, making scenes an integral part of your design.

Adding the Scene Manager

To use the Scene Manager:

  1. Import the Scene Manager component from the Asset Library, if it's not already in your project.
  2. Drag the Scene Manager custom component from the Asset Browser panel into your Scene Hierarchy panel. This creates a new Scene Object with the Scene Manager component attached.
  3. Position the Scene Object containing the Scene Manager at the top of your Scene Hierarchy. This ensures it initializes before other parts of your project attempt to reference it.
  4. Access the Scene Manager in your scripts via the global.sceneManager object.

If you've previously installed the Scene Manager, you can add it like any other component:

  1. In the Scene Hierarchy panel, click "+" > "Scene Object".
  2. Select the newly created Scene Object.
  3. In the Inspector panel, click "+ Add Component" > "Scene Manager".

Creating a Scene

A scene is fundamentally an Object Prefab. To create a scene:

  • Drag a Scene Object from the Scene Hierarchy panel into the Asset Browser panel.
  • Alternatively, right-click a Scene Object in the Scene Hierarchy and select "Save as Prefab".

For optimal performance, especially with loadSceneAsync, enable "Lazy Asset Loading" on your Object Prefabs. This setting, found in the Inspector panel when a Prefab is selected, delays loading scene assets until they are needed. This drastically improves Lens startup time by avoiding the upfront loading of all scene assets. Instead, only assets associated with the specific prefab/scene are loaded when required.

Registering Scenes

After creating your scene prefabs:

  1. Select the Scene Manager object you added earlier.
  2. In the Inspector panel, click the "Add Value" button on the Scene Manager component. This adds a new slot to the scene registry.
  3. For each registry item, provide a unique name and assign the corresponding prefab. You'll use this name (case and space sensitive) to reference the scene later.

The Scene Manager also supports Prefabs designated as remote assets. Adding a remote asset prefab creates a "Remote Scene" registry item. Only asynchronous loading (loadSceneAsync) is permitted for Remote Scenes, as the scene must be downloaded first.

Loading and Unloading Scenes

Scenes are loaded using one of two methods. Key parameters are explained below:

// ** Sample Code with All Parameters **
// Load a scene synchronously
global.sceneManager.loadSceneSync('scenename', {
// Optional parameters
additive: true, // Default value: true
enabled: true, // Default value: true
parent: undefined, // Default value: undefined (Scene Manager's object)
});

// Load a scene asynchronously
global.sceneManager.loadSceneAsync('scenename', {
// Optional parameters
additive: true, // Default value: true
enabled: true, // Default value: true
parent: undefined, // Default value: undefined (Scene Manager's object)
onProgress: (percentage) => {
print(`Loading progress: ${percentage * 100}%`);
}, // Default value: null
loadingScene: 'scenename', // Optional loading scene name
onComplete: (loadedScene) => {
print('Scene has been loaded successfully');
}, // Default value: null
onFailure: (errorMsg) => {
print('ERRPR: Scene loading failed: ' + errorMsg);
}, // Default value: null
});

Additive vs. Non-Additive Loading

The Scene Manager supports two scene loading modes: additive and non-additive.

  • Non-Additive Scenes: When a non-additive scene is loaded, any currently active non-additive scene is automatically unloaded. This is analogous to switching levels in a game. Only one non-additive scene can be active at a time. This is ideal for major sections of your Lens, such as different gameplay areas or distinct UI screens.

  • Additive Scenes: Additive scenes load on top of existing scenes, acting like layers. This allows you to build complex experiences by combining multiple scenes. This is suitable for elements like UI overlays, special effects, or additional content that shouldn't replace the main scene. Multiple additive scenes can be stacked.

Custom Scene Root (Parent)

By default, loaded scenes become children of the Scene Manager's Scene Object. However, you can specify a different parent for a loaded scene using the parent parameter in loadSceneSync and loadSceneAsync. This provides finer control over your Scene Hierarchy and ensures correct functionality, especially for scenes using Screen Transforms or Orthographic Cameras that might require specific parent objects (like a camera).

global.sceneManager.loadSceneSync('myScene', { parent: myCameraObject });

Alternatively, you can achieve the same result without code using the Behavior component's "Scene Manager: Load Scene" action. Set the "Scene Root Object" field to the desired parent.

Asynchronous Loading and Loading Scenes

The Scene Manager enables asynchronous scene loading, meaning the loading process occurs in the background without blocking the rest of your Lens. This is particularly useful for large or complex scenes that might take some time to load. While a scene loads asynchronously, you can display a "loading scene" to provide feedback to the user.

A loading scene is simply a regular scene (prefab) registered with the Scene Manager. Specify the loading scene using the loadingScene parameter in loadSceneAsync. It's crucial that your loading scene is lightweight and optimized. Complex animations or heavy assets in the loading scene can defeat its purpose.

You can also set a minimum display time for the loading scene using the minLoadingTimeInSeconds property of the Scene Manager. This ensures the loading scene is visible for a specified duration, even if the main scene loads quickly, contributing to a smoother user experience.

Scene Hooks (Pre-Unload)

Scene hooks allow you to execute custom logic before a scene unloads. This is valuable for cleanup tasks, playing animations, or saving data. Currently, the Scene Manager supports only the preUnloadHook.

The preUnloadHook is a function defined in a script attached to the root object of the scene you intend to unload. This function must return a Promise. The Scene Manager will wait for this Promise to resolve before unloading the scene.

// In a script attached to the root object of your scene:
script.preUnloadHook = function () {
return new Promise((resolve) => {
// Perform some action, e.g., an animation or data saving.
// ...
resolve(); // Resolve the Promise when the action is complete.
});
};

Behavior Script Integration (No-Code Scene Management)

The Scene Manager integrates seamlessly with Behavior scripts, allowing you to load and unload scenes without writing any code. The "Scene Manager: Load Scene" action in Behavior provides options to specify the scene, loading mode (additive/non-additive), and other parameters. This makes the Scene Manager accessible to users less familiar with scripting.

Learn more about Behavior scripts here.

API Reference

The Scene Manager provides a set of properties and methods accessible through the global.sceneManager object.

Properties

  • verbose: boolean (Read/Write) - Controls verbose logging.
  • extensions: Array<SceneManagerExtension> (Read-Only) - An array of extensions added to the Scene Manager.
  • minLoadingTimeInSeconds: number (Read/Write) - The minimum display time (in seconds) for loading screens.
  • root: SceneObject (Read-Only) - The root Scene Object where scenes are loaded (by default, the Scene Manager's object).
  • onSceneLoaded: Event<LoadedScene> (Read-Only) - An event triggered when a scene is loaded.
  • onSceneUnloaded: Event<LoadedScene> (Read-Only) - An event triggered when a scene is unloaded.

Methods

loadSceneSync(name: string, options?: Object): LoadedScene

Loads a scene synchronously.

Parameters:

  • name (string, required): The name of the scene (as defined in the Scene Manager's registry).
  • options (object, optional): An object with optional parameters:
    • additive: boolean (default: true) - Whether to load the scene additively.
    • enabled: boolean (default: true) - Whether the scene should be enabled after loading.
    • parent: SceneObject (default: undefined) - The parent Scene Object for the loaded scene. If undefined, the Scene Manager's object is used.

Returns:

  • LoadedScene: A LoadedScene object representing the newly loaded scene.

loadSceneAsync(name: string, options?: Object): Promise<LoadedScene>

Loads a scene asynchronously.

Parameters:

  • name (string, required): The name of the scene.
  • options (object, optional): An object with optional parameters:
    • additive: boolean (default: true) - Whether to load additively.
    • enabled: boolean (default: true) - Whether the scene should be enabled after loading.
    • parent: SceneObject (default: undefined) - The parent Scene Object.
    • onProgress: (percentage: number) => void (default: null) - A callback function called with the loading progress (0 to 1).
    • loadingScene: string (default: null) - The name of a scene to display while loading.
    • onComplete: (loadedScene: LoadedScene) => void (default: null) - A callback function called when loading is complete.
    • onFailure: (errorMsg: string) => void (default: null) - A callback function called if loading fails.

Returns:

  • Promise<LoadedScene>: A Promise that resolves with the LoadedScene object when loading is complete or rejects with an error message if loading fails.

registerScene(registryItem: SceneRegistryItem, override?: boolean): SceneRegistryItem | undefined

Registers a new scene in the Scene Manager's registry.

Parameters:

  • registryItem: SceneRegistryItem, The item to register.
  • override: boolean, optional, if true and there is a naming conflict, will override existing item.

Returns: SceneRegistryItem if successfully registered, otherwise returns undefined.

unregisterScene(sceneName: string): void

Unregisters a scene from the registry.

Parameters:

  • sceneName: string, The name of the scene to be unregistered.

Throws: Error, if scene name is not found in registry.

findSceneByPrefab(prefab: ObjectPrefab): SceneRegistryItem | undefined

Finds a registered scene by its prefab.

findScenePrefabByName(sceneName: string): SceneRegistryItem | null

Finds a registered scene by its name.

getCurrentScene(requester: SceneObject): {myScene: LoadedScene, climbCount: number}

Gets the current parent scene of a given Scene Object.

unloadSceneByName(registryName: string): void

Unloads all instances of a scene, given its registry name.

unloadScenes(scenes: LoadedScene[], onUnloadCompleteCallbacks?: Function[]): void

Unloads an array of LoadedScene objects.

unloadScene(scene: LoadedScene, onUnloadComplete?: Function): void

Unloads a single LoadedScene.

isLoaded(sceneName: string): LoadedScene[] | false

Checks if a scene with the given name is currently loaded.

dontDestroyOnUnload(sceneObject: SceneObject): void

Marks a Scene Object to prevent it from being destroyed when its parent scene unloads.

Object Types

These are the primary object types used by the Scene Manager:

SceneRegistryItem

Represents a registered scene.

  • sceneName: string (Read-Only) - The name of the scene.
  • sceneAsset: ObjectPrefab | RemoteReferenceAsset (Read-Only) - The prefab or remote asset associated with the scene.
  • type: "Asset.ObjectPrefab" | "Asset.RemoteReferenceAsset" (Read-Only) - The type of asset.
  • objectPrefab: ObjectPrefab | undefined - Cached prefab (if type is "Asset.ObjectPrefab").

LoadedScene

Represents a scene that has been loaded.

  • manager: SceneManager (Read-Only) - The Scene Manager instance that loaded the scene.
  • loadedTime: number (Read-Only) - The timestamp when the scene was loaded.
  • sceneRoot: SceneObject (Read-Only) - The root Scene Object of the loaded scene.
  • source: SceneRegistryItem (Read-Only) - The SceneRegistryItem from which the scene was loaded.
  • isAdditive: boolean (Read-Only) - Whether the scene was loaded additively.
  • state: string - The current state of the loaded scene.
Was this page helpful?
Yes
No