Universal Camera - move on the xz plane always

I’m using a Universal Camera and noticed that when I face straight down and hit forward (in my case I assigned W to it), you don’t actually move. Since I want to control like Doom and not like Descent, I want my “forward” action to be full speed on the XZ plane and not my camera forward vector. Is there a property I’m missing on the Universal camera, or do I need to add some more logic?

I guess you will need custom logic.

@PolygonalSun any quick trick ?

Yeah, I’m afraid that you’ll need some custom input work to make that happen. The easiest way that I see to do this would be to create a custom camera input that just extends FreeCameraKeyboardMoveInput and just overrides checkInputs() to handle the movements:

class FreeCameraXZKeyboardInput extends BABYLON.FreeCameraKeyboardMoveInput {
    checkInputs() {
        const camera = this.camera;
        const front = camera.getDirection(BABYLON.Axis.Z);
        const right = camera.getDirection(BABYLON.Axis.X);
        if (this._keys.length > 0) {
            front.y = 0;
            front.normalize();

            right.y = 0;
            right.normalize();
        }

        for (let index = 0; index < this._keys.length; index++) {
            const keyCode = this._keys[index];
            const speed = camera._computeLocalCameraSpeed();
            camera._localDirection.copyFromFloats(0,0,0);

            if (this.keysLeft.indexOf(keyCode) !== -1) {
                camera._localDirection.subtractInPlace(right);
            } else if (this.keysUp.indexOf(keyCode) !== -1) {
                camera._localDirection.addInPlace(front);
            } else if (this.keysRight.indexOf(keyCode) !== -1) {
                camera._localDirection.addInPlace(right);
            } else if (this.keysDown.indexOf(keyCode) !== -1) {
                camera._localDirection.subtractInPlace(front);
            }

            camera._localDirection.scaleInPlace(speed);

            if (camera.getScene().useRightHandedSystem) {
                camera._localDirection.z *= -1;
            }
            camera.cameraDirection.addInPlace(camera._localDirection);
        }
    }
}

This class is just a basic implementation of what I was saying (PG Example). Since we’re only overriding the checkInputs() function, all of the other functionality (including assigning keys), should remain intact. Lemme know if this works for you.

Thank you for this, it is basically exactly what I need.

I did see that when I tried to plug it in to my Typescript project I am getting this error

image

The _keys variable needs to be protected in order to be accessed by subclasses.

@PolygonalSun could you expose _keys in a nice way so that inherited classes can consume it safely ?

@BoldBigflank you could cas as any for now as a workaround.

I could make _keys protected so that it’s exposed but doesn’t affect backwards compatibility. Either that or I could just create a getter to expose it. Lemme get back to you once I have something in place.

1 Like

sounds good to me