Scenes generated later lose Keyboard focus

So while trying to make a game with babylonjs I have noticed that scenes generated later seem to lose keyboard focus. For instance if I have a menu and then when I click a button to start a game level the button disposes of the menu scene and creates a new scene with the level meshes, materials, etc. Then for some reason even though I added an action listener to detect keyboard input it detects nothing unless the user clicks outside the canvas and back on it. I apologize though, try as I might (and I tried for hours) I could not replicate this problem on the playground, so posted below is the code for a nodejs example.

import {Engine} from '@babylonjs/core/Engines/engine';
import {ExecuteCodeAction} from '@babylonjs/core/Actions/directActions';
import {Vector3} from '@babylonjs/core/Maths/math';
import {Camera} from '@babylonjs/core/Cameras/camera';
import {Scene} from '@babylonjs/core/scene';
import {ActionManager} from '@babylonjs/core/Actions/actionManager';

import {AdvancedDynamicTexture} from '@babylonjs/gui/2D/advancedDynamicTexture';
import {Button} from '@babylonjs/gui/2D/controls/button';

var canvas = document.getElementById("renderCanvas");
var engine = new Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });

var doit = () => {
	engine.scenes[0].dispose();
	activeDisplay = new Game(engine);
	//activeDisplay = later;
}

class Menu{
	constructor(engine){
		this.screenWidth = engine.getRenderWidth()
		this.screenHeight = engine.getRenderHeight();
		
		this.scene = new Scene(engine);
		this.gui = AdvancedDynamicTexture.CreateFullscreenUI("UI",true,this.scene);
		this.camera = new Camera("camera",new Vector3(0,0,-10),this.scene); 
		
		this.start = new Button.CreateSimpleButton("start", "Game");
		this.start.width = .2;
		this.start.height = "40px";
		this.start.color = "white";
		this.start.background = "green";
		this.start.onPointerUpObservable.add(doit);
		this.gui.addControl(this.start);  
	}
}

class Game{
	constructor(engine){
		this.scene = new Scene(engine);
		this.scene.clearColor.r = 1;
		this.camera = new Camera("camera",new Vector3(0,0,-10),this.scene); 
		this.scene.actionManager = new ActionManager(this.scene);
		this.scene.actionManager.registerAction(new ExecuteCodeAction(ActionManager.OnKeyDownTrigger, (evt) => {
			switch(evt.sourceEvent.key){
				case 'p':
					console.log("The Key p was pressed");
			}
		}));
		//engine._onCanvasFocus();
	}
}

var activeDisplay = new Menu(engine);
//var later = new Game(engine);

engine.runRenderLoop(function(){
	if (activeDisplay) {
		activeDisplay.scene.render();
	}
});

As you can see it starts by creating my game menu and then when you click the button it changed to the next scene(I made the background red so you can tell it changed). The odd thing is if you uncomment the two lines with the variable later it works, so it seems that creating the scene early will keep the keyboard but not later? Also if you uncomment the engine._onCanvasFocus() line it will also work but I don’t understand why I would need to have the engine refocus if it never lost focus. Although it would technically work with the onCanvasFocus line I don’t like that this feels like a hack, because if there is one thing that I have learned from coding it is that patching a bug with a hack instead of fixing the underlying issue with almost certainly lead to more bugs down the road. So what I’m trying to figure out is the root cause of this issue which I suspect has something to do with the Observers since that is what the onCanvasFocus method invokes but I can’t seem to figure it out.
Any help is appreciated. Also feel free to add me on discord 8Bit#6510 since I feel that this issue will have a lot of back and forth with what I have already tried and sharing information. Also I’m relatively new to babylon, so if there is a better approach to making a multilevel game than creating and disposing of a bunch of scenes please let me know. Thank you.

This looks like a bug from back in May, are you on the latest version?

Yes I am, I did the “npm install --save-dev @babylonjs/core” and followed the instructions on the es6_support page about a week ago so I am using a very recent version (4.0.3) , maybe the bug was somehow reintroduced? Also where is your link suppose to go, it just links back to this page?

EDIT: Oh, looking at the npm module page 4.0.3 was released 4 months ago and would be before the bug was patched, according to the npm page there are alpha versions out afterwords, but how do I install the alpha versions?

The link was supposed to go here.

For the alpha you can do:

npm install --save-dev @babylonjs/core@preview

Ok, so I installed alpha.15 but now I am getting this error
“Uncaught LoadFileError: Error status: 404 Not Found - Unable to load src/Shaders/layer.vertex.fx”
why is babylon looking for the layer.vertex.fx file outside the babylon module? Also thank you for your help so far.

EDIT: I’m an idiot, I was also using @babylonjs/gui in my program and I updated the core to use the alpha version but not the gui and that incompatibility caused the error, but you are right, after updating to the new version it has fixed the bug that this post was originally about. Thank you.

1 Like