docs
Getting Started
Tutorials
How-To Guides
Explanation
Reference
Help
Getting Started
Tutorials
How-To Guides
Explanation
Reference
Help

Camera Controls (OrbitControls)

The primary camera controller for navigating and exploring 3D scenes with intuitive mouse, touch, and keyboard controls.

Works with Unity and Blender

The OrbitControls component is available for both Unity and Blender integrations.

What You Can Do

  • Rotate - Orbit around objects by dragging
  • Pan - Move the camera side-to-side (right-click drag or two-finger touch)
  • Zoom - Scroll to zoom in/out
  • Auto-Rotate - Automatically rotate the camera around the scene
  • Auto-Fit - Automatically frame the entire scene
  • Focus on Click - Double-click objects to focus on them
  • Smooth Animations - Animate camera movements programmatically

Perfect for:

  • Product showcases and configurators
  • Architectural visualizations
  • Interactive 3D models
  • Any scene requiring camera control
  • All Needle Engine projects (it's the default!)

Quick Start

Default Behavior

OrbitControls is typically added automatically to your camera in Unity or Blender. Just export and you're ready to go!

Controls:

  • Left-click drag - Rotate around the scene
  • Right-click drag or Two-finger touch - Pan the camera
  • Mouse wheel or Pinch - Zoom in/out
  • Double-click - Focus on the clicked object

Adding Manually

In Unity or Blender:

  1. Select your camera object
  2. Add the OrbitControls component
  3. Export - camera controls are now active!

Core Features

Auto-Rotate

Automatically rotate the camera for presentations:

In Editor:

  1. Enable Auto Rotate on the OrbitControls component
  2. Set Auto Rotate Speed (default is 1.0)
  3. The camera rotates automatically - any user interaction stops it

From Code:

import { Behaviour, OrbitControls } from "@needle-tools/engine";

export class AutoRotateExample extends Behaviour {
    start() {
        const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);
        if (orbit) {
            orbit.autoRotate = true;
            orbit.autoRotateSpeed = 2.0; // Rotate twice as fast
        }
    }
}

Auto-Fit to Scene

Automatically frame the entire scene when it loads or when users click the background:

In Editor:

  • Enable Auto Fit - Camera frames all objects on start
  • Set Click Background To Fit Scene - Number of clicks on background to re-fit (default: 2)

Users can double-click the background at any time to re-fit the camera to the entire scene.

From Code:

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);
orbit?.fitCamera(); // Fit entire scene

Focus on Objects

Users can double-click objects to focus the camera on them. Configure this behavior:

SettingWhat it doesDefault
Double Click To FocusFocus on object when double-clickedtrue
Middle Click To FocusFocus on object when middle-clickedtrue
Click Background To Fit SceneNumber of clicks on background to fit entire scene2

Settings

Rotation Controls

SettingWhat it doesDefault
Enable RotateAllow camera rotationtrue
Auto RotateAutomatically rotate camerafalse
Auto Rotate SpeedRotation speed when auto-rotating1.0
Min Azimuth AngleMinimum horizontal rotation (radians)Infinity (no limit)
Max Azimuth AngleMaximum horizontal rotation (radians)Infinity (no limit)
Min Polar AngleMinimum vertical rotation (radians)0
Max Polar AngleMaximum vertical rotation (radians)Math.PI

Zoom Controls

SettingWhat it doesDefault
Enable ZoomAllow zoomingtrue
Zoom SpeedHow fast zooming happens1
Zoom To CursorZoom toward cursor position instead of centerfalse
Min ZoomMinimum zoom distance0
Max ZoomMaximum zoom distanceInfinity

Pan Controls

SettingWhat it doesDefault
Enable PanAllow panningtrue

Movement Feel

SettingWhat it doesDefault
Enable DampingSmooth, inertial movementtrue
Damping FactorHow much damping (lower = more smooth)0.1
Enable KeysAllow keyboard controlsfalse

Behavior

SettingWhat it doesDefault
Auto TargetAutomatically find focus pointtrue
Auto FitFit scene to view on startfalse
Allow InterruptUser input stops animationstrue
Target Lerp DurationAnimation duration in seconds1

Examples

Product Viewer

Create a product showcase that auto-rotates until touched:

import { Behaviour, OrbitControls } from "@needle-tools/engine";

export class ProductViewer extends Behaviour {

    start() {
        const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

        if (orbit) {
            // Auto-rotate the product
            orbit.autoRotate = true;
            orbit.autoRotateSpeed = 0.5;

            // Fit the product in view
            orbit.fitCamera();

            // Stop rotation when user interacts
            orbit.onStartInteraction(() => {
                orbit.autoRotate = false;
            });
        }
    }
}

Restrict Camera Movement

Limit rotation to prevent users from seeing under/behind objects:

import { Mathf, OrbitControls } from "@needle-tools/engine";

// In your component
const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

if (orbit) {
    // Prevent looking directly up or down
    orbit.minPolarAngle = Mathf.toRadians(30);  // 30 degrees from top
    orbit.maxPolarAngle = Mathf.toRadians(80);  // 80 degrees from top

    // Limit horizontal rotation
    orbit.minAzimuthAngle = Mathf.toRadians(-45);  // -45 degrees
    orbit.maxAzimuthAngle = Mathf.toRadians(45);   // +45 degrees
}

Animate Camera to Position

Smoothly move camera to look at a specific object:

import { Behaviour, OrbitControls, serializable } from "@needle-tools/engine";
import { Object3D } from "three";

export class FocusObject extends Behaviour {

    @serializable(Object3D)
    targetObject?: Object3D;

    focusOnTarget() {
        const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

        if (orbit && this.targetObject) {
            // Animate camera to look at the target
            orbit.setCameraAndLookTarget(this.targetObject);

            // Or set positions separately:
            // orbit.setLookTargetPosition(this.targetObject.worldPosition);
            // orbit.setCameraTargetPosition(cameraPosition);
        }
    }
}

Fit Specific Objects

Frame specific objects instead of the whole scene:

import { Behaviour, OrbitControls } from "@needle-tools/engine";
import { Object3D } from "three";

export class FitObjects extends Behaviour {

    fitToObjects(objects: Object3D[]) {
        const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

        if (orbit) {
            orbit.fitCamera({
                objects: objects,
                immediate: false, // Animate to the new view
            });
        }
    }
}

Keyboard Controls

Enable keyboard navigation:

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

if (orbit) {
    orbit.enableKeys = true;

    // Users can now use:
    // Arrow keys - Pan camera
    // Default three.js orbit controls keys are used
}

Scripting API

Camera Movement

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

// Rotate the camera
orbit.rotateLeft(0.1);  // Rotate left in radians
orbit.rotateUp(-0.1);   // Rotate down in radians

// Pan the camera
orbit.pan(10, 0);  // Pan 10 pixels right

// Zoom
orbit.zoomIn(0.1);   // Zoom in 10%
orbit.zoomIn(-0.1);  // Zoom out 10%

Camera Animations

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

// Animate camera position
orbit.setCameraTargetPosition(newPosition, 2.0); // 2 second duration

// Animate look target
orbit.setLookTargetPosition(targetPosition, 1.5); // 1.5 second duration

// Set immediately (no animation)
orbit.setCameraTargetPosition(newPosition, true);

// Stop ongoing animations
orbit.stopCameraLerp();
orbit.stopLookTargetLerp();

// Check if animating
if (orbit.cameraLerpActive) {
    console.log("Camera is moving...");
}

Field of View

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

// Animate FOV change
orbit.setFieldOfView(60, 1.0); // Change to 60° over 1 second

// Set immediately
orbit.setFieldOfView(45, true);

Fitting Camera

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

// Fit entire scene
orbit.fitCamera();

// Fit specific objects
orbit.fitCamera({
    objects: [object1, object2],
    immediate: false,  // Animate to view
});

// Advanced options
orbit.fitCamera({
    objects: myObjects,
    immediate: false,
    centerCamera: "y",  // Only center on Y axis
    fov: 50,            // Set field of view
});

Access Three.js Controls

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

// Access underlying three.js OrbitControls
const threeControls = orbit.controls;

if (threeControls) {
    // Direct access to three.js properties
    console.log("Distance:", threeControls.getDistance());
    console.log("Azimuth:", threeControls.getAzimuthalAngle());
    console.log("Polar:", threeControls.getPolarAngle());

    // Access the camera being controlled
    console.log("Camera:", orbit.controllerObject);
}

Events

import { OrbitControls, OrbitControlsEventsType } from "@needle-tools/engine";

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

// Listen for user interaction
orbit.onStartInteraction(() => {
    console.log("User started interacting with camera");
});

// Listen for camera target reached
orbit.addEventListener(OrbitControlsEventsType.CameraTargetReached, (evt) => {
    console.log("Camera reached target:", evt.detail.type);
    // evt.detail.type is either "camera" or "lookat"
});

Advanced Features

Look At Constraints

Make the camera always look at a specific object:

In Editor:

  1. Create a LookAtConstraint component
  2. Assign the target object to the constraint
  3. Assign the constraint to Look At Constraint on OrbitControls

The camera will always look at the constrained object while users control it.

Target Bounds

Restrict where users can pan the camera:

In Editor:

  1. Create an empty object to define the bounds
  2. Scale it to the desired size
  3. Assign it to Target Bounds on OrbitControls

Users can only pan within this defined volume.

Custom Dom Element

Make OrbitControls listen to a different HTML element:

const orbit = this.context.mainCameraComponent?.getComponent(OrbitControls);

if (orbit) {
    orbit.targetElement = document.getElementById("my-custom-element");
}

Common Questions

How do I disable camera controls temporarily?
Disable the OrbitControls component: orbit.enabled = false;

Can users control the camera in VR/AR?
OrbitControls automatically disables in XR mode. Camera control happens through the headset instead.

Why does auto-rotate stop when I interact?
This is default behavior. Auto-rotation resumes only if you re-enable it via script.

How do I prevent users from seeing under the floor?
Set Min Polar Angle and Max Polar Angle to limit vertical rotation.

Can I change controls sensitivity?
Yes! Adjust Damping Factor (lower = smoother), Zoom Speed, and Auto Rotate Speed.

How do I focus camera on an object immediately?
Use orbit.setCameraAndLookTarget(targetObject, true); - the true makes it instant.

Can I use keyboard controls?
Enable Enable Keys to allow arrow key navigation.

Performance Tips

Damping: Damping creates smooth motion but requires updates every frame. For static presentations, you can disable it once camera settles.

Auto-Rotate: Auto-rotation updates every frame. Disable when not needed to save performance.

Manual Updates: For very static scenes, consider handling camera control yourself and disabling OrbitControls entirely.

Debugging

Enable debug mode by adding ?debugorbit to your URL:

http://localhost:3000?debugorbit

This shows:

  • Camera look target as a green sphere
  • Raycast hit points
  • Detailed logging of camera operations

Other debug parameters:

  • ?freecam - Unlock all camera restrictions
  • ?smoothcam or ?smoothcam=0.95 - Override damping factor
  • ?debugcamerafit - Log camera fitting operations

More Information

API Documentation:

  • OrbitControls API - Complete technical reference
  • three.js OrbitControls - Underlying three.js implementation

Related Components:

  • Camera - Camera component settings
  • LookAtConstraint - Constrain camera look target
Suggest changes
Last Updated: 1/28/26, 4:48 PM

Extras

ChatGPT Ask ChatGPT Claude Ask Claude
Copy Markdown

Navigation

  • Getting Started
  • Tutorials
  • How-To Guides
  • Explanation
  • Reference
  • Help

Extras

ChatGPT Ask ChatGPT Claude Ask Claude
Copy Markdown