Key takeaways:
Three.js is a JavaScript framework built on WebGL, providing an abstraction layer that simplifies working with 3D graphics.
FlyControls allow for free camera movement within a scene, contrasting with OrbitControls that focus on a specific target.
FlyControls are found in the add-ons directory and can be imported to enhance scene navigation.
Camera and event listener are constructor parameter. The scene’s camera is passed as an argument and event listener listens for user inputs like mouse movements and clicks.
dispose()
detaches the controls from user input when they are no longer needed.
update()
must be called every frame to refresh controls, utilizing the time delta from thegetDelta()
method.
getDelta()
normalizes control updates across different hardware speeds, ensuring consistent behavior regardless of frame rate.Users can navigate the scene using keyboard controls (WASD) and mouse movements for looking around.
autoForward()
moves the camera forward automatically if set to true.
dragToLook()
allows users to look around by dragging the mouse.
movementSpeed()
adjusts the speed of the camera movement.
Three.js is a JavaScript framework based on
Three.js allows us to traverse the scenes we create using different kinds of controls. In this Answer, we’ll examine one way we can move through our scene using a unique type of user control: FlyControls.
The FlyControls
class OrbitControls
class does.
FlyControls are present in the addons/
directory of the three.js repository and can be imported using the following statement:
import { FlyControls } from 'three/addons/controls/FlyControls.js';
Once they’ve been imported, we can use the constructor as follows:
const controls = new FlyControls( object, domElement );
The constructor takes the following arguments:
The scene camera: This is denoted by object
in the constructor above.
The event listener: This is denoted by the domElement
argument in the constructor. It will listen for events such as mouse movement and mouse clicks.
The FlyControls
class has some methods associated with it. One is the dispose()
method. This method detaches the controls from user input once they are not required. We can use the following line of code to detach the controls:
controls.dispose()
Like every other Controls
class, FlyControls
also needs to be updated in every frame that is rendered. So we’ll need to add the following statement, which updates the controls as follows:
controls.update(delta)
The update()
method for these controls requires a time delta value, which is obtained using the getDelta()
method. Let's go into a little detail about what this parameter means.
Note: The
update()
method is used inside the looping function which is called once per every frame.
getDelta()
methodIn three.js, we have to use an animate()
function, which is called once every frame to update the values and variables that are being used in a scene. Now consider this: we have two computers. One is really fast, let’s call that A, and the other is very slow, denoted by B. The number of times the fast computer will call the animate loop function per minute will be a lot more times than B. The update()
function for FlyControls, will resultantly end up being called a lot more times than on computer B. To fix this issue, we use the getDelta()
method. This method returns the inverse of the number of frames being called per second, which is used by the update()
method to normalize the controls according to the number of frames being called per second. This way, FlyControls will work in the same manner on both A and B.
Here’s how we can get the number:
const clock = new THREE.Clock();const delta = clock.getDelta()
In the scene shown below, some cubes have been added in the scene in a random order to help with navigation. The camera can be controlled using the “WASD” keys on the keyboard, along with mouse movement, which can be used for looking around.
The skeleton code for setting up the scene has already been set up. We can play around with the code and tweak stuff to see how it affects the output. Let’s have a look at how FlyControls are being used in the code:
Line 25: Here, we import FlyControls from the path that contains the FlyControls
class.
Lines 41–42: After initializing the controls, here we set the camera rotation speed using the rollSpeed()
method.
Lines 52–65: Here, we generate a bunch of cubes in our scene that will be floating around at random coordinates.
Line 73: Finally, in the animate()
function we’ll call the update()
method and pass it the inverse of frames per second, delta
, which we got on the previous line using the getDelta()
method.
Here are some of the important properties for FlyControls that have to do with movement inside the scene. All of them can be invoked using the dot operator. For example, flycontrols.autoForward()
.
Method name | Type | Description |
| Boolean | If set to true, this will cause the camera to move forward on its own. |
| Boolean | If this is set to true, it will allow the user to only look around by dragging on the screen. |
| Number | This sets the movement speed for the camera. |
Without adding controls to a scene, the user doesn’t really have any options for freely viewing what they’re creating. FlyControls are similar to camera controls in modern game development engines such as Unity and Unreal and can really help with navigating the scene to better view what we’re creating.
Free Resources