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();
});
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.