scene.unregisterBeforeRender not stopping ArcRotateCamera motion previously registered

Hi everyone!

I’m currently working on creating a camera (“Museum”) mode where, when the mode is toggled with a button click, the one ArcRotateCamera in the scene slowly, continuously rotates around its centerpoint. I have the button toggling the Redux state correctly, my handler is correctly printing the state, and the rotation motion is functioning as expected once turned on, but I can’t get it to turn off.

I’m using registerBeforeRender successfully whenever the Museum mode is toggled on, but unable to use unregisterBeforeRender when Museum mode is toggled off. Am I misunderstanding how to use it? (Note that I’ve tried to use unregisterBeforeRender in a conditional part of my registerBeforeRender function, a style which I’ve seen a couple places online, and I’ve tried to have registerBeforeRender and unregisterBeforeRender get called separately depending on my mode boolean:


let previousState: StateProps = {
    museumModeOn: false
};

function stateChangeHandler(
    state: StateProps,
    manager: C.StateManager,
    dispatcher: DispatcherProps,
    scene: BABYLON.Scene
): void {

    if (previousState.museumModeOn !== state.museumModeOn) {
        // Register a function that rotates the ArcRotateCamera on each render when museumModeOn gets toggled to true
        scene.registerBeforeRender(function museumRotateCamera() {
            if (state.museumModeOn) {
                if (state.camera != null) {
                    state.camera.useAutoRotationBehavior = true;
                }
            }
            // Unregister the function when museumModeOn gets toggled off
            else {
                if (state.camera != null) {
                    scene.unregisterBeforeRender(museumRotateCamera);
                }
            }
        });
    }
}

Either put your function to outer scope, like as class-function:

Or use it as variable:

2 Likes

when your camera is ArcRotateCamera
and target set

camera.lockedTarget = targetObject;

try to this

camera.useAutoRotationBehavior = true;

when you want stop try this

camera.useAutoRotationBehavior = false;

Hey there, thanks for the response! Can I ask how your suggestion is different than what I’m currently doing in the StateChangeHander, here? Maybe I’m missing something?

Hi, thanks so much for your reply and the playground. I recreated the formatting you’ve used, but I’m not seeing any change in the behavior:

    function museumRotateCamera() {
        if (state.camera != null) {
            state.camera.useAutoRotationBehavior = true;
            state.camera.autoRotationBehavior!.idleRotationSpeed = 0.07;
            state.camera.autoRotationBehavior!.idleRotationSpinupTime = 10;
            state.camera.autoRotationBehavior!.idleRotationWaitTime = 10;
        }
        // Unregister when museumModeOn gets toggled off
        if (!state.museumModeOn) {
            scene.unregisterBeforeRender(museumRotateCamera);
        }
    }

    if (previousState.museumModeOn !== state.museumModeOn) {
        console.log('Museum Mode:', state.museumModeOn);
        // Register rotation every render when museumModeOn gets toggled to true
        if (state.museumModeOn) {
            scene.registerBeforeRender(museumRotateCamera);
        }
    }

Hi, I don’t know exactly if you can unregister a function inside of itself, but why not something like this

function museumRotateCamera() {
  if (state.camera != null) {
      state.camera.useAutoRotationBehavior = true;
      state.camera.autoRotationBehavior!.idleRotationSpeed = 0.07;
      state.camera.autoRotationBehavior!.idleRotationSpinupTime = 10;
      state.camera.autoRotationBehavior!.idleRotationWaitTime = 10;
  }
}
...

if (state.museumModeOn) {
    scene.registerBeforeRender(museumRotateCamera);
}
else {
   scene.unregisterBeforeRender(museumRotateCamera);
}


Later edit, you can do this without register too

if (state.museumModeOn) {
   state.camera.useAutoRotationBehavior = true;
}
else {
   state.camera.useAutoRotationBehavior = false;
}
1 Like

Hi MarianG,

Thanks so much for pointing that I can do this while bypassing the registerBeforeRender() function. So clear in retrospect but exactly what I needed. Cheers

1 Like