Skip to main content
Version: 4.55.1

Scene Manager

By loading a Lens in parts, you can dramatically improve Lens performance on device, which can increase reach, views, plays, and other engagement metrics. The Scene Manager custom component is necessary for organizing a Lens into scenes.

This powerful component enables easy scene management through functions like loadSceneSync, loadSceneAsync, unloadScene, and unloadSceneByName. The Scene Manager is essential for working with scenes in Lens Studio, whether you're building a multi-level game or a multi-layered lens.

This guide will walk through the basic functions and how to use it. With the Scene Manager, you can:

  • Compartmentalize your lens into logical scenes, keeping your project organized.
  • Quickly load and unload scenes as needed with simple functions.
  • Manage scene transitions smoothly with async scene loading.
  • Unload scenes by name to free up resources.
  • Build multi-scene games, interactive stories, and more.

By following this guide and studying the Scene Manager Template, you'll learn how to leverage this powerful component and even improve Lens performance.

Adding Scene Manager

To use the Scene Manager custom component:

  1. Import the Scene Manager component from the Asset Library if it is not already present.
  2. Drag and drop the Scene Manager custom component into your Objects panel to create a scene object containing this component.
  3. Position the scene object with the Scene Manager component at the top of your Objects panel. This ensures the Scene Manager initializes before other parts of the project reference it.
  4. The Scene Manager will be accessible through the global.sceneManager object in scripts.

Now that we have our Scene Manager, we can prepare our scenes.

If you've installed Scene Manager before, you can just add the component as you would with any other component.

  1. Objects panel > + > Scene Object.
  2. Select the Scene Object.
  3. In the Inspector panel > + Add Component > Scene Manager.

Creating a Scene

Technically, a scene is simply an Object Prefab. To create an Object Prefab:

  • Drag a Scene Object into the Resources panel
  • Or right-click on a Scene Object and use the "Save as Prefab" option

If using the Scene Manager's asynchronous loading (loadSceneAsync method), please remember to enable "Lazy Asset Loading" on the Object Prefab. This serializes/loads the Scene only when the Scene Manager loads it, improving the performance and speeding up the starting up speed of your Lens.

Registering the Scene to Scene Manager

Once you have created the needed Object Prefabs:

  1. Select the Scene Manager we created earlier.
  2. Click the "Add Value" button on the Scene Manager to add a new slot in the scene registry.
  3. Each registry item needs a name and prefab. Refer to the scene later using this name (case and space sensitive).

Scene Manager also supports Prefabs made into remote assets. This creates a Remote Scene registry item. Only asynchronous loading using the loadSceneAsync method is allowed for Remote Scenes, as the scene needs to be downloaded first.

Loading the Scene

You can load a scene by calling one of the two methods:

// Load a scene synchronously
global.sceneManager.loadSceneSync('scenename', {
// Optional parameters
additive: true, // Default value
enabled: true, // Default value
parent: undefined, // Default value
});

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

In many cases, you can load scenes without writing code using Behavior!

Consider the necessity of loading scenes with caution. Loading scenes may not be needed for small to mid-sized scenes that load instantly, as they can cause confusion. Implement loading scenes only for large, complex scenes that require additional loading time, or to display a splash screen for branding purposes before the experience begins. If you opt for a loading scene, set its minimum display time by assigning a value to `global.sceneManager.minLoadingTimeInSeconds`` (the default value is 0.1 seconds). This setting controls the minimum duration for which the loading scene appears.

Example

Take a look at the Scene Manager Template to see these capabilities in action.

APIs

Scene manager provides a set of useful properties and functions you can use throughout the global.sceneManager object.

Here are the public API methods and properties for the SceneManager class with more details:

Properties

  • verbose: boolean, can be written, controls verbose logging.
  • extensions: Array<SceneManagerExtension>, readonly, array of extensions added to the scene manager.
  • minLoadingTimeInSeconds: number, can be written, minimum on display in seconds for loading scenes, the default value is 0.1 (seconds).
  • root: SceneObject, readonly, the root scene object to load scenes into.
  • onSceneLoaded: Event<LoadedScene>, readonly, event fired when a scene is loaded.
  • onSceneUnloaded: Event<LoadedScene>, readonly, event fired when a scene is unloaded.

Methods

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

Loads a scene synchronously given a local scene name and optional parameters for additive loading, enabled state, and custom parent.

Parameters:

  • name (required): The name of the scene to load.
  • options (optional): An object containing optional parameters.
  • additive (default: true): Whether the scene should be loaded additively.
  • enabled (default: true): Whether the scene should be loaded as enabled or disabled (hidden).
  • parent (default: null): If not null, the newly loaded scene will be placed under this Scene Object.

Returns:

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

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

Loads a scene asynchronously given a name and optional parameters like onProgress callbacks, additive loading, custom parent, etc. Returns a Promise.

Parameters:

  • name (required): The name of the scene to load.
  • options (optional): An object containing optional parameters.
  • additive (default: true): Whether the scene should be loaded additively.
  • enabled (default: true): Whether the scene should be loaded as enabled or disabled (hidden).
  • parent (default: null): If not null, the loaded scene will be placed under this Scene Object.
  • onProgress (default: null): A callback function called during loading with the progress percentage (0-1).
  • loadingScene (default: null): The name of a scene to load during the background loading process.
  • onComplete (default: null): A callback function called when loading is completed, passed the loaded scene object.
  • onFailure (default: null): A callback function called if loading fails, passed an error message.

Returns:

A Promise that resolves with the LoadedScene object when loading is complete.

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

Registers a new scene registry item, overriding existing item if override is true. Returns the registered item or undefined on failure.

unregisterScene(sceneName: string): void

Unregisters a scene registry item given a scene name. Throws error if not found.

findSceneByPrefab(prefab: ObjectPrefab): SceneRegistryItem | undefined

Finds a registry item for a given prefab asset. Returns item or undefined if not found.

findScenePrefabByName(sceneName: string): SceneRegistryItem | null

Finds a registry item by name. Returns item or null if not found.

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

Gets the current parent scene of a given scene object requester by climbing its hierarchy.

unloadSceneByName(registryName: string): void

Unloads all instances of a scene given its registry name.

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

Unloads an array of scenes, optionally accepting callbacks per scene.

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

Unloads a single scene, optionally accepting a callback when completed.

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

Checks if a scene is loaded by name. Returns an array of LoadedScene or false.

dontDestroyOnUnload(sceneObject: SceneObject): void

Prevents a scene object from being destroyed when its parent scene unloads.

Object Types

These are object types being used extensively by Scene Manager, if you plan to interface Scene Manager by scripting, you likely will need to deal with these object types.

SceneRegistryItem

Holds information about a registered scene - its name, asset source, and type.

  • sceneName: string, readonly, the name of the scene
  • sceneAsset: ObjectPrefab | RemoteReferenceAsset, readonly, the prefab or remote asset for the scene
  • type: "Asset.ObjectPrefab" | "Asset.RemoteReferenceAsset", readonly, the type of asset
  • objectPrefab: ObjectPrefab | undefined, package access, cached prefab if type is prefab

LoadedScene

Represents a scene that has been loaded, holds metadata like the time loaded, root object, etc.

  • manager: SceneManager, readonly, the SceneManager that loaded this
  • loadedTime: number, readonly, timestamp when loaded
  • sceneRoot: SceneObject, readonly, root object of loaded scene
  • source: SceneRegistryItem, readonly, registry source
  • isAdditive: boolean, readonly, if loaded additively
  • state: string, package access, current state
Was this page helpful?
Yes
No