Every Babylon.js camera will automatically handle inputs for you... once you call the camera's attachControl function. And you can revoke the control by using the detachControl function. Most Babylon.js experts use a two-step process to activate and attach a camera:
//First, set the scene's activeCamera... to be YOUR camera.
scene.activeCamera = myCamera;
// Then attach the activeCamera to the canvas.
//Parameters: canvas, noPreventDefault
scene.activeCamera.attachControl(canvas, true);
A simpler version might look like this:
myCamera.attachControl(canvas);
By default noPreventDefault is set to false, meaning that preventDefault() is automatically called on all canvas mouse clicks and touch events.
Some of Babylon.js's cameras respond to user inputs. This is especially true for Arc Rotate Camera and Universal Camera.
Babylon.js v2.4 introduced a different way to manage camera inputs to provide an approach oriented toward composability of inputs. These cameras now use an input manager and each input can be seen as a plugin that is specific to this camera family, and to a given input type (mouse, keyboard, gamepad, device orientation, ...).
Using input manager, you can add, remove, enable, or disable any input available for the camera. You can also implement your own input mechanism or override the existing one, very easily.
The input manager is available on these cameras through a property called "inputs".
var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
var inputManager = camera.inputs;
Most inputs provide settings to customize the sensibility and adapt it to your own scene.
Each input provides a short name available on the manager. The goal is to provide a friendly syntax when playing with your inputs.
var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.add(new BABYLON.FreeCameraGamepadInput());
camera.inputs.attached.gamepad.gamepadAngularSensibility = 250;
Input manager of both ArcRotateCamera and FreeCamera expose short-hand functions for adding built-in inputs.
var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.addGamepad();
If you wish, you can also add an instance of your own input (we will cover how to implement your own input at the end of this article).
var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.add(new BABYLON.FreeCameraGamepadInput());
When you call "attachControl" on the camera, you are activating all inputs attached to the input manager. In the same way, you could turn off all inputs by calling "detachControl" on the camera.
If you want to disable an input temporarily, you can call "detachControl" directly on the input... like this:
var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.attached.mouse.detachControl();
camera.inputs.addGamepad();
You can then call "attachInput" when you want to turn it on again.
camera.inputs.attachInput(camera.inputs.attached.mouse);
Sometimes you want a very specific input mechanism. The best approach in such case is probably to clear all inputs and add only those you may want in your scene.
var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.clear();
camera.inputs.addMouse();
You can also remove a single input from your input manager. You can remove them by instance, or by Type name
var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
//remove by instance
camera.inputs.remove(camera.inputs.attached.mouse);
//remove by type
camera.inputs.removeByType("FreeCameraKeyboardMoveInput");
The input must be provided to the input manager as an object instance with a few required functions. If you use TypeScript, you could implement the interface ICameraInput.
Even if you don't use TypeScript for your project, you will probably understand the signature of the input from the interface
interface ICameraInput<TCamera extends BABYLON.Camera> {
// the input manager will fill the parent camera
camera: TCamera;
//this function must return the type name of the camera, it could be used for serializing your scene
getTypeName(): string;
//this function must return the simple name that will be injected in the input manager as short hand
//for example "mouse" will turn into camera.inputs.attached.mouse
getSimpleName(): string;
//this function must activate your input, event if your input does not need a DOM element
attachControl: (element: HTMLElement, noPreventDefault?: boolean) => void;
//detach control must deactivate your input and release all pointers, closures or event listeners
detachControl: (element: HTMLElement) => void;
//this optional function will get called for each rendered frame, if you want to synchronize your input to rendering,
//no need to use requestAnimationFrame. It's a good place for applying calculations if you have to
checkInputs?: () => void;
}