UniversalCamera Lower Upper Beta Limit?

How could I limit the UniversalCamera Lower Upper Beta Limit?
Similar to ArcRotateCamera, but for first person camera.



You already cc @PolygonalSun , GG, @PolygonalSun you are becoming famous !!! :slight_smile:

1 Like

Hello @a_bolog , how are you doing?

I did a small playground sample with a possible solution for you. In the onViewMatrixChangedObservable I’m checking the view Matrix rotation component and forcing it to be within the constrains of the Upper and Lower bounds.

Lower Higher Beta Limit | Babylon.js Playground (babylonjs.com)

Does that help you?

Let me know your thoughts on that!

1 Like

Hey man, that’s exactly the effect I’m looking for.
But the camera gets stuck if I move it left right, does it happen on your end too?
I can see that these camera values still change even if the camera is locked… hmm

I was playing around with the camera.rotation.x to somehow clamp it between +70 and -70 but can’t figure out how, maybe that’s an easier approach?

function clamp(number, min, max) {
  return Math.max(min, Math.min(number, max));

Many thanks

@a_bolog , I did an updated version that handles that fixes the camera lock issue. I think it is a little more complicated than it should be right now, but maybe it gets the job done?

Lower Higher Beta Limit | Babylon.js Playground (babylonjs.com)


Using the view matrix to limit movement is a pretty awesome approach. Another approach I could recommend would be to remove the mouse input and just manually rotate things.

    scene.onPointerObservable.add((eventData) => {
        let angularSensibility = 2000;
        if (scene.getEngine().isPointerLock) {
            let evt = eventData.event;
            let offsetX = evt.movementX || evt.mozMovementX || evt.webkitMovementX || evt.msMovementX || 0;
            camera.rotation.y += offsetX / angularSensibility;

            const offsetY = evt.movementY || evt.mozMovementY || evt.webkitMovementY || evt.msMovementY || 0;
            let tentativeY = camera.rotation.x + offsetY / angularSensibility;
            if (Math.abs(tentativeY) < (MAX_ROTATION)) {
                camera.rotation.x += offsetY / angularSensibility;
    }, BABYLON.PointerEventTypes.POINTERMOVE);


Yes, it’s more predictable and enjoyable to use now.
But I notice that it’s loosing the camera.inertia effect?

Many thanks for helping out guys.

Hello @a_bolog just checking in, was your question answered?

Thanks for checking in, but not really, as it doesn’t work on the UniversalCamera without loosing inertia and touch controls on mobile.
I was hoping maybe there is a more elegant way the same way it’s on ArcRotateCamera, beta limitXY