Changing camera works fine and throws an error

Hi everybody,

I am currently trying to switch cameras and I’m having a strange error. It has ben difficult to reproduce the same error in the playground and with the same code, I have another error. Here’s the playground link: https://playground.babylonjs.com/#6PX1XQ#2

What result is expected from the PlayGround script?
There are two cameras set up. One is a arcCamera that show the sphere+ground from the top. The second is a UniversalCamera that shows the same scene from an angle. The script uses the arcCamera and should switchTo the UniversalCamera instantly.

What do I get?
main.js:1 TypeError: Cannot read property ‘attachControl’ of undefined
at switchCameraTo (:53:19)
at createScene (:60:5)
at :73:9
at fastEval (main.js:1)
at main.js:1

This is original code, which is the one I’m trying to solve. Here “cam” is a string transmitted from a button. It’s either arcCamera, uniCamera1 or uniCamera2.

switchCameraTo(cam) {
    let newCamera;

    switch (cam) {
        case "arcCamera":
            newCamera = this.scene.cameras[0];
            break;
        case "uniCamera1":
            newCamera = this.scene.cameras[1];
            break;
        case "uniCamera2":
            newCamera = this.scene.cameras[2];
            break;
    }
    this.scene.cameras.forEach( (camera) =>{
        camera.detachControl(this.canvas);
    });

    this.scene.activeCamera =  newCamera; 

    this.scene.activeCamera.attachControl(this.canvas, true);
}

This code works but also throws this following error:
Uncaught TypeError: Cannot read property ‘addEventListener’ of undefined
at e.attachControl (babylon.js:16)
at t.e.attachElement (babylon.js:16)
at t.attachControl (babylon.js:16)
at HTMLElement.switchCameraTo (scene.js?df63:175)
at HTMLElement.attributeChangedCallback (scene.js?df63:56)
at HTMLElement.set camera [as camera] (scene.js?df63:45)
at eval (viz-app.js?3375:24)
at Array.forEach ()
at HTMLElement.onMutationChange (viz-app.js?3375:20)
at MutationObserver.eval (viz-app.js?3375:10)

Maybe someone can point out my mistake. Thank you!

Your PG does not work because you pass this.scene instead of scene to the UniversalCamera constructor: https://playground.babylonjs.com/#6PX1XQ#4

As for your other problem, it will be difficult to know as it seems your code is embedded in a container (viz-app.js). However, looking at the error, it seems this.canvas is undefined when calling this.scene.activeCamera.attachControl.

… speechless.

Ok, it works: this.canvas was undefined and as soon as I fixed it, all was working properly. Thank you very much.

… however, I want to know what made you think/know that there was a canvas reference issue? I think this will be very helpful because I could not make sense of the error message.

Thank you!

That’s your stack trace:

  • switchCameraTo
  • t.attachControl
    So the problem occurs after calling this.scene.activeCamera.attachControl.

This method attaches some events to the canvas you pass in parameters, and as addEventListener is the method used to attach events on a HTML element, it follows that the canvas is probably the target of the error.

2 Likes

Well explained.

Thank you. I’ll be analyzing the error message more carefully from now on.