Skip to content

anna-claudette/godot-cinematic-camera

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Godot Cinematic Camera

A production-ready cinematic camera system for Godot 4.x.

Drop it into any 3D project and get smooth tracking, scripted camera moves, rail followers, profile presets, shot sequencing, and screen shake -- all from GDScript with a clean, chainable API.

Features

  • Tracking camera -- orbit-style framing around one or two targets with configurable distance, height, angle, tilt, and smoothing
  • Scripted moves -- smooth tween-based transitions between positions with move_to(), instant cuts with hold_at()
  • Camera profiles -- reusable CameraProfile resources with built-in presets (close-up, medium shot, wide shot, dramatic low, bird's eye, over-the-shoulder, telephoto)
  • Rail follower -- drive the camera along a Path3D with look-at targeting, speed control, easing curves, looping, and pause/resume
  • Shot sequencer -- chain shots into timed sequences with per-shot callbacks, transitions, and hold times
  • Screen shake -- noise-based trauma system with quadratic falloff for organic-feeling impacts
  • Fully exported -- all parameters exposed to the Inspector; works in @tool mode for editor previews

Installation

  1. Copy the addons/cinematic_camera/ folder into your project's addons/ directory.
  2. The scripts use class_name registration, so Godot will pick them up automatically -- no plugin activation required.
  3. Add a CinematicCamera node to your scene (it extends Camera3D).
your_project/
  addons/
    cinematic_camera/
      cinematic_camera.gd
      camera_profile.gd
      rail_follower.gd
      shot_sequence.gd
      plugin.cfg

Quick Start

Basic tracking

@onready var camera: CinematicCamera = $CinematicCamera
@onready var player: Node3D = $Player

func _ready() -> void:
    camera.track(player)

Apply a profile

# Built-in presets
camera.apply_profile(CameraProfile.close_up())
camera.apply_profile(CameraProfile.dramatic_low())

# Custom profile
var profile := CameraProfile.create("my_shot", 8.0, 3.0, 50.0, 15.0, 5.0)
camera.apply_profile(profile)

Scripted camera move

# Smooth move over 3 seconds
var tween := camera.move_to(Vector3(10, 5, 10), player.global_position, 40.0, 3.0)
await tween.finished

# Instant cut
camera.hold_at(Vector3(0, 2, 5), player.global_position, 55.0, true)

# Resume tracking after a scripted move
camera.resume_tracking()

Screen shake

camera.shake(0.6, 0.4)  # intensity 0-1, duration in seconds
await camera.shake_completed

Shot sequence

var seq := ShotSequence.new(camera)

seq.add_shot({
    "position": Vector3(-5, 3, 8),
    "look_at": Vector3.ZERO,
    "fov": 35.0,
    "duration": 2.0,
    "transition": ShotSequence.Transition.SMOOTH,
    "hold": 1.0,
})
seq.add_shot({
    "position": Vector3(0, 10, 0.1),
    "look_at": Vector3.ZERO,
    "fov": 60.0,
    "duration": 1.5,
    "transition": ShotSequence.Transition.CUT,
})

seq.play()
await seq.sequence_completed

Rail camera

var rail := RailFollower.new()
add_child(rail)
rail.path = $CameraRail       # a Path3D with a Curve3D
rail.camera = $CinematicCamera
rail.look_at_target = $Player
rail.speed = 5.0
rail.start()
await rail.rail_completed

API Reference

CinematicCamera

Extends Camera3D. The main camera node.

Method Description
hold_at(pos, look_at, fov, cut) Position the camera at a world position. cut=true teleports instantly.
move_to(pos, look_at, fov, duration) -> Tween Smooth tween to a position. Returns the Tween for chaining/awaiting.
set_framing(distance, height, fov, angle, tilt) Configure orbit framing parameters.
track(target, secondary?) Set tracking target(s) and enter tracking state.
resume_tracking() Resume tracking after a scripted move.
shake(intensity, duration) Trigger screen shake. Stacks additively.
apply_profile(profile) Apply a CameraProfile resource.
get_state() -> State Returns IDLE, TRACKING, or SCRIPTED.
Signal Description
move_completed Emitted when a move_to tween finishes.
shake_completed Emitted when shake finishes.
tracking_changed(primary, secondary) Emitted when targets change.
Export Default Description
default_fov 70.0 Default field of view.
smoothing_speed 5.0 Position interpolation speed.
look_smoothing_speed 8.0 Look-at interpolation speed.
framing_distance 10.0 Orbit distance from target.
framing_height 2.0 Height offset from target.
framing_angle 0.0 Horizontal orbit angle (degrees).
framing_tilt 0.0 Vertical tilt (degrees).
max_trauma 1.0 Maximum shake trauma.
trauma_decay 1.5 Trauma decay rate per second.

CameraProfile

Extends Resource. A reusable set of framing parameters.

Static Method Distance Height FOV Angle Tilt
close_up() 2.5 1.5 35 0 0
medium_shot() 6.0 2.0 55 0 0
wide_shot() 18.0 4.0 70 0 5
dramatic_low() 5.0 -2.0 40 15 -15
birds_eye() 25.0 20.0 60 0 60
over_the_shoulder() 3.0 1.8 50 25 5
telephoto() 40.0 3.0 20 0 2

Use CameraProfile.create(name, distance, height, fov, angle, tilt, smoothing) to build custom profiles.

RailFollower

Extends Node3D. Drives a camera along a Path3D.

Method Description
start() Begin following the rail.
pause() / resume() Pause and resume movement.
stop() Stop and reset to the beginning.
seek(ratio) Jump to a position (0.0 to 1.0).
get_progress_ratio() -> float Current progress along the rail.
Signal Description
rail_started Emitted when the rail begins.
rail_completed Emitted when the camera reaches the end.
progress_updated(ratio) Emitted each frame with current progress.
Export Default Description
path null The Path3D to follow.
camera null The CinematicCamera to drive.
look_at_target null Optional node to look at while on the rail.
speed 5.0 Movement speed (units/sec).
loop false Loop back to start on completion.
autoplay false Start automatically on _ready().
ease_curve null Optional Curve for easing.

ShotSequence

Extends RefCounted. Chains shots into a timed sequence.

Method Description
add_shot(dict) -> ShotSequence Append a shot. Returns self for chaining.
play(from_index?) Start playing.
pause() / unpause() Pause and resume.
skip() Skip to the next shot.
stop() / reset() Stop and reset.
size() -> int Number of shots.
Signal Description
sequence_completed Emitted when all shots finish.
shot_changed(index) Emitted when a new shot begins.

Shot dictionary keys:

Key Type Required Description
position Vector3 Yes Camera position.
look_at Vector3 Yes Look-at target.
fov float No Field of view (0 = use default).
duration float No Transition time in seconds (default 1.0).
transition Transition No CUT or SMOOTH (default SMOOTH).
hold float No Seconds to hold before next shot.
profile CameraProfile No Apply this profile on enter.
on_enter Callable No Called when shot begins.
on_exit Callable No Called when shot ends.

Running the Demo

  1. Open the project in Godot 4.x.
  2. Open examples/demo_scene.tscn.
  3. Press F5 (or set it as the main scene).
  4. Press Space to advance through demo steps. Press R to reset.

License

MIT License. See LICENSE.

Credits

Built by Colossus Forge Studios.

About

Production-ready cinematic camera system for Godot 4.x — tracking, rails, profiles, shot sequencing

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors