How can change between multiple scenes in babylonjs editor?

Hello, I am creating small game which consists of 7 to 8 different scenes, I just get started using babylon js editor , How can change between multiple scenes ? I also want to play videos between scene changing, to make a story

Hello and welcome

When you create a scene, you must put it in an array:

var scenes = [];
scenes["SCENE1"] = new BABYLON.Scene(engine);
scenes["SCENE2"] = new BABYLON.Scene(engine);

And in your render loop, you display the scene of your choice.

var activeScene = "SCENE2";

engine.runRenderLoop(() => {
      scenes[activeScene].render();
});
1 Like

Hello, I followed the things you suggested and suggestion which I got from other community member, but still I am getting same error of

Uncaught Error: No camera defined

scene contains camera too, I have verified it by logging it but I don’t know I am still getting that error

Following is my index.ts code (I am using babylonjs editor)


import { BabylonFileLoaderConfiguration, Engine, Scene, SceneLoader } from "@babylonjs/core";
import "@babylonjs/materials";

import * as CANNON from "cannon";
import { Key } from "readline";

import { appendScene } from "./scenes/tools";

export class Game {
    /**
     * Defines the engine used to draw the game using Babylon.JS and WebGL
     */
    public engine: Engine;
    /**
     * Defines the scene used to store and draw elements in the canvas.
     */
    public scene: Scene;
    // public allScenes:{[key: string]: Scene}[]=[];
    // public activeScene:string;

    /**
     * Constructor.
     */
    public constructor() {
        // console.log("allScenes",this.allScenes);
        
        this.engine = new Engine(document.getElementById("renderCanvas") as HTMLCanvasElement, true);
        let scene1=new Scene(this.engine);
        let scene2 = new Scene(this.engine);    
        // this.allScenes["scene1"]=scene1;
        // this.allScenes["scene2"]=scene2;
        // this.allScenes.push({"scene2":scene2})
        // console.log("allscene",this.allScenes["scene1"]);
        
        // this.activeScene="scene2"



        // this.scene = new Scene(this.engine);
        this.scene = scene1;

        this._bindEvents();
        this._load("scene");
        setTimeout(() => {
            console.log("changing scene ........");
            if (this.scene.activeCamera) {
                this.scene.activeCamera.detachControl(this.engine.getRenderingCanvas());
                console.log("dertaching ");
                
            }
            // this.scene.dispose();
            // this.scene = scene2;
            // // console.log("this scene ",this.scene);
            
            // // this.activeScene="scene1"
            // this._load("scene1");
            // this._bindEvents();




             this.scene.dispose();

            // Load new scene.
            this.scene = scene2;
            this.scene.setActiveCameraByName("Camera scene 1");
            
            this._load("scene1");

        }, 10000);
    }

    /**
     * Loads the first scene.
     */
    private async _load(sceneName:string): Promise<void> {
        const rootUrl = "./scenes/_assets/";

        BabylonFileLoaderConfiguration.LoaderInjectedPhysicsEngine = CANNON;

        
            
        
        console.log("scenename ",sceneName);
        // console.log("this.scene",this.scene);
        

        
        await appendScene(this.scene, rootUrl, `../${sceneName}/scene.babylon`);

        this.scene.executeWhenReady(() => {
            // this.engine.stopRenderLoop();
            // Attach camera.
            console.log("this scene active camera",this.scene._activeCamera);
            console.log("this scene active camera--------",this.scene.activeCamera);
            
            // if (this.scene.activeCamera) {
            //     this.scene.activeCamera.detachControl(this.engine.getRenderingCanvas());
            //     console.log("detaching camera");
                
            // }

            if (!this.scene.activeCamera) {
                throw new Error("No camera defined in the scene. Please add at least one camera in the project or create one yourself in the code.");
            }
            this.scene.activeCamera.attachControl(this.engine.getRenderingCanvas(), false);




            // if (this.scene.activeCamera !== camera) {
            //     this.scene.activeCamera.detachControl(this.engine.getRenderingCanvas());
            //     this.scene.activeCamera = camera;
            //     this.scene.activeCamera.attachControl(this.engine.getRenderingCanvas(), false);
            // }


            // Render.
            this.engine.runRenderLoop(() => this.scene.render());
        });


       
    }

    /**
     * Binds the required events for a full experience.
     */
    private _bindEvents(): void {
        window.addEventListener("resize", () => this.engine.resize());
    }
}




What i want to eventually is.
I have 7 8 scenes I want my user to move from one scene to another scene.

I recently discovered the editor and am experimenting with it.
If disposing scenes is okay (which enables the use of the lifecycle methods), take a look at this code (index.ts):

// see index.html
declare global {
    var game: Game;
}

export class Game {
    /**
     * Defines the engine used to draw the game using Babylon.JS and WebGL.
     */
    public engine: Engine;
    /**
     * Defines the scene used to store and draw elements in the canvas.
     */
    public scene: Scene | null = null;

    /**
     * Constructor.
     */
    public constructor() {
        BabylonFileLoaderConfiguration.LoaderInjectedPhysicsEngine = CANNON;
        this.engine = new Engine(document.getElementById("renderCanvas") as HTMLCanvasElement, true);

        this._bindEvents();
        this.loadScene("scene/scene.babylon");

        // Render.
        this.engine.runRenderLoop(() => this.scene?.render());
    }

    private disposeScene() {
        if (this.scene == null) {
            return;
        }
        this.scene.dispose();
        this.scene = null;
    }

    /**
     * Loads a scene.
     */
    async loadScene(sceneFileName: string): Promise<void> {
        this.disposeScene();

        const scene = new Scene(this.engine);
        const rootUrl = "./scenes/_assets/";
        await appendScene(scene, rootUrl, "../" + sceneFileName);

        // Attach camera.
        if (!scene.activeCamera) {
            throw new Error("No camera defined in the scene. Please add at least one camera in the project or create one yourself in the code.");
        }

        scene.activeCamera.attachControl(this.engine.getRenderingCanvas(), false);
        this.scene = scene;
    }

    /**
     * Binds the required events for a full experience.
     */
    private _bindEvents(): void {
        window.addEventListener("resize", () => this.engine.resize());
    }
}

This allows you to load a scene from anywhere (for example, in response to a click):

export default class MyScript extends Node {
    // ...

    @onPointerEvent(PointerEventTypes.POINTERPICK)
    test() {
        game.loadScene("scene2/scene.babylon");
    }
}

Each scene must have one camera and a light.

If you create only one camera on scene 1, it will not be shared with scene 2. You must create as many cameras as you have scenes.