bevy_director 0.2.0

Unreal-Sequencer-inspired cinematic camera and sequence system for Bevy
Documentation

bevy_director

Shots, sequences, and a camera you can direct. An Unreal-Sequencer-shaped cinematic layer for Bevy 0.19: sequences are RON assets made of shots, shots are camera rigs (eased keys, constant-speed dolly rails, orbits) with a film-literate lens (focal length against a filmback, focus pulls, aperture, exposure), and playback hands off from your gameplay camera and glides back onto it when the take ends.

What it is not: a general tween library (see bevy_tweening) or an animation graph (see bevy_animation). Its editor is deliberately focused on cinematic cameras and events rather than being a general scene editor.

Quickstart

use bevy::prelude::*;
use bevy_director::prelude::*;

app.add_plugins(DirectorPlugin);

// Let the director borrow the frame: gate your own camera-driving
// system so it yields during a take and runs during the glide home.
app.add_systems(Update, my_camera_rig.run_if(gameplay_camera_free));

// Anywhere, later:
commands.play_sequence(asset_server.load("sequences/intro.dir.ron"));

The director finds your active Camera3d, snapshots it, swaps is_active to its own CineCamera (spawning a plain one if you did not provide one; spawn your own to keep your post stack), plays the shots, and at the end blends toward wherever your live camera is by then, sampling it every frame. Control can return to the player while the camera is still gliding.

Listen for SequenceStarted, MarkerReached { name, .. } (captions, stingers), and SequenceFinished { reason } (story flags belong here, never on markers). commands.skip_sequence() jumps to the end and takes the normal blend home; stop_sequence() cuts hard.

Director's Cut (feature editor, opt-in)

Director's Cut is the docked, mouse-driven authoring surface. It uses the same ViewfinderSession, evaluator, and .dir.ron assets as the runtime, so there is no conversion or editor-only project format.

use bevy::prelude::*;
use bevy_director::prelude::*;

App::new()
    .add_plugins((DefaultPlugins, DirectorsCutPlugin))
    .run();

Run the included stage with:

cargo run --example directors_cut --features editor

Press Backquote to possess the camera; Director's Cut opens automatically. Press Tab to switch between the editor cursor and camera piloting.

Action Control
Move a shot Drag its body
Resize a shot Drag its bright right edge
Retime a transform or lens key Drag the diamond
Scrub Click or drag the timeline
Edit camera values Select a key; use the inspector for position, rotation, FOV/focal value, and time
Capture the current camera Key button
Add a camera cut Shot button
Preview Play button or Space
Undo / redo Ctrl+Z / Ctrl+Y
Open / save Ctrl+O / Ctrl+S
Rename the sequence file Click the pencil filename; Enter confirms and Escape cancels
Zoom timeline zoom-out / zoom-in buttons in the toolbar

New/Open/Save use assets/sequences/<sequence name>.dir.ron by default. The filename field accepts either a plain name or the full .dir.ron filename; the extension is added exactly once. Set DirectorsCutConfig::sequence_path when a fixed path is preferable. The editor feature is not enabled by default, keeping UI and picking out of shipping builds unless requested.

Development vs shipping

Enabling a Cargo feature only makes its code available. A tool becomes active—and starts reading its shortcuts—only when its plugin is added to the app.

Setup What runs
DirectorPlugin Sequence playback only. No authoring shortcuts or UI.
(DirectorPlugin, ViewfinderPlugin) Playback plus the keyboard/mouse capture mode. Backquote opens the viewfinder.
DirectorsCutPlugin The complete authoring setup: runtime, viewfinder, timeline UI, Bevy 0.19's infinite grid, and editor shortcuts. It installs the other required plugins automatically.

For a game that authors cinematics during development but ships only the RON player, expose the editor through a game-specific feature:

[features]
director_editor = ["bevy_director/editor"]

[dependencies]
bevy_director = { version = "0.2", default-features = false }

Select the plugin at compile time:

#[cfg(feature = "director_editor")]
app.add_plugins(DirectorsCutPlugin);

#[cfg(not(feature = "director_editor"))]
app.add_plugins(DirectorPlugin);

Use the authoring build to create and save the asset:

cargo run --features director_editor

Then run or release the normal game without that feature:

cargo run
cargo build --release

The shipping build loads and plays the saved asset normally:

commands.play_sequence(asset_server.load("sequences/intro.dir.ron"));

It contains no Director's Cut UI or editor shortcuts because DirectorsCutPlugin is not installed. This also makes Director's Cut usable as a temporary authoring tool whose only shipped output is the .dir.ron sequence.

The editor's infinite grid appears only while the viewfinder is active. Disable it when the game already supplies an authoring grid:

app.insert_resource(DirectorsCutConfig {
    show_grid: false,
    ..default()
});

The spawned entity is marked with DirectorsCutGrid; you can despawn it and add your own InfiniteGrid and InfiniteGridSettings when you need custom colors, spacing, or fade distance.

The viewfinder (feature viewfinder, on by default)

The director's chair, no widgets: press Backquote in your running game.

Key Action
Backquote Toggle the viewfinder (possesses the camera at the current view)
WASD + mouse Fly and look
Q / E Sink / rise
Wheel Fly speed (Ctrl+Wheel: fov)
K Capture the framing as a key at the playhead
[ / ] Scrub (Shift: single frame)
P Preview the working take
Delete Remove the nearest key
Ctrl+S Write assets/sequences/<name>.dir.ron (native only)

Gizmos draw every shot's path, keys, aim rays, and the playhead ghost while the viewfinder is up.

The .dir.ron format

SequenceAsset(
    name: "intro",
    shots: [
        Shot(
            start: 0.0, duration: 8.0,
            rig: Rail(
                points: [(-2.0, 2.0, -6.0), (0.0, 2.2, 0.0), (2.0, 2.5, 6.0)],
                constant_speed: true,
                progress: ScalarTrack(keys: [
                    ScalarKey(time: 0.0, value: 0.0, ease: SmoothStep),
                    ScalarKey(time: 8.0, value: 1.0),
                ]),
            ),
            look: At(target: Entity("gate"), damping: Some(8.0)),
            lens: Lens(
                fov: FocalLengthMm(track: ScalarTrack(keys: [ScalarKey(time: 0.0, value: 35.0)])),
                focus: Some(Target(target: Entity("gate"))),
                aperture_f_stops: Some(ScalarTrack(keys: [ScalarKey(time: 0.0, value: 2.0)])),
            ),
        ),
    ],
    markers: [Marker(time: 1.0, name: "caption_one")],
    blend_out: Some(Blend(secs: 1.5, ease: SmoothStep)),
)

Rules worth knowing: shot starts are absolute and sorted; a shot with no blend_in cuts hard; during a blend the previous shot is sampled clamped (extend it into the overlap for a moving crossfade); markers fire only while playing across them (skips and seeks never retro-fire); constant_speed rails cover equal distance in equal time via an arc-length table, the piece Bevy itself does not ship.

Glossary for Unreal refugees

Unreal Sequencer bevy_director
Level Sequence asset SequenceAsset (.dir.ron)
Sequencer (the editor) Director's Cut (editor feature)
Camera Cuts track the shot list itself
CineCameraActor a CineCamera entity
Ease In/Out on a section Blend (blend_in / blend_out)
Camera Rail rig Rig::Rail
Crane / orbit rig Rig::Orbit
Transform keyframes Rig::Keys
Look-at Tracking Look::At { target, damping }
Filmback Filmback presets (Super35 default)
Focal Length FovSpec::FocalLengthMm
Focus Settings FocusTrack -> bevy DepthOfField
Event track Marker -> MarkerReached
Play Rate SequencePlayer::rate (negative plays backward)
Possess / Eject the handoff and DirectorPhase::Handback
Pilot camera viewfinder fly mode
Camera Shake Shake (seeded, deterministic)

Features

  • viewfinder (default): the in-game capture mode. Implies gizmos.
  • gizmos (default): path and key overlay drawing.
  • editor (opt-in): Director's Cut dock, camera inspector, timeline, undo/redo, and open/save. Implies viewfinder.

With both off, the crate is the data model, the evaluator, the RON loader, and the playback state machine: enough to ship cutscenes.

Compatibility

bevy bevy_director
0.19 0.1–0.2

License

Dual-licensed under MIT or Apache-2.0, at your option.