Work in progress. This crate is in active development and not subject to semver stability guarantees. APIs will change without notice between commits. Do not depend on this in production code yet.
A camera controller for Bevy that combines smooth orbit controls with event-driven camera operations — zoom-to-fit, queued animations, and a debug overlay for fit targets.
- Smooth orbit, pan, and zoom with configurable limits
- Zoom-to-fit, look-at, and queued camera animations with easing
- Event-driven control with full lifecycle events for sequencing
- Orthographic and perspective projection, multi-viewport, render-to-texture
- Touch, trackpad, and
bevy_eguisupport - Debug overlay for fit targets (optional
fit_overlayfeature)
Add the plugin and spawn a camera:
use bevy::prelude::*;
use bevy_lagrange::LagrangePlugin;
use bevy_lagrange::OrbitCam;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(LagrangePlugin)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn((
Transform::from_translation(Vec3::new(0.0, 1.5, 5.0)),
OrbitCam::default(),
));
}OrbitCam automatically requires Camera3d. Out of the box you get orbit, pan, and zoom with smoothing. For perspective cameras, the default near clip plane scales with orbit radius so close-up zooming does not clip away the target.
Default mouse controls:
| Input | Action |
|---|---|
| Left Mouse | Orbit |
| Right Mouse | Pan |
| Scroll Wheel | Zoom |
Default touch controls:
| Input | Action |
|---|---|
| One finger | Orbit |
| Two fingers | Pan |
| Pinch | Zoom |
All controls are configurable via OrbitCam fields — buttons, modifiers, sensitivity, smoothness, and limits.
Enable the fit_overlay feature:
bevy_lagrange = { version = "...", features = ["fit_overlay"] }Frame a target entity in the camera view:
commands.trigger(
ZoomToFit::new(camera, target)
.margin(0.15)
.duration(Duration::from_millis(800))
.easing(EaseFunction::CubicOut),
);Rotate the camera in place to face a target:
commands.trigger(
LookAt::new(camera, target)
.duration(Duration::from_millis(600)),
);Animate to a chosen yaw/pitch while framing the target:
commands.trigger(
AnimateToFit::new(camera, target)
.yaw(PI / 4.0)
.pitch(PI / 6.0)
.duration(Duration::from_millis(1200)),
);Chain multiple movements into a sequence:
commands.trigger(PlayAnimation::new(camera, [
CameraMove::ToOrbit {
focus: Vec3::ZERO,
yaw: 0.0,
pitch: 0.5,
radius: 5.0,
duration: Duration::from_millis(800),
easing: EaseFunction::CubicOut,
},
]));All operations support instant (Duration::ZERO) and animated paths with full lifecycle events for sequencing.
| Feature | Default | Description |
|---|---|---|
fit_overlay |
no | Zoom-to-fit, camera animations, event-driven control, and debug overlay |
bevy_egui |
no | Prevents camera movement when interacting with egui windows |
bevy_lagrange |
Bevy |
|---|---|
| 0.0.3 | 0.18 |
- Plonq —
bevy_lagrangebuilds on bevy_panorbit_camera, with permission
All code in this repository is dual-licensed under either:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.
