godot-camera-systems

安装量: 73
排名: #10668

安装

npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-camera-systems
Camera Systems
Expert guidance for creating smooth, responsive cameras in 2D and 3D games.
NEVER Do
NEVER use
global_position = target.global_position
every frame
— Instant position matching causes jittery movement. Use
lerp()
or
position_smoothing_enabled = true
.
NEVER forget
limit_smoothed = true
for Camera2D
— Hard limits cause sudden stops at edges. Smoothing prevents jarring halts.
NEVER use offset for permanent camera positioning
offset
is for shake/sway effects only. Use
position
for permanent camera placement.
NEVER enable multiple Camera2D nodes simultaneously
— Only one camera can be active. Others must have
enabled = false
.
NEVER use SpringArm3D without collision mask
— SpringArm clips through walls if
collision_mask
is empty. Set to world layer
Available Scripts
MANDATORY
Read before implementing camera behaviors. camera_follow_2d.gd Smooth camera following with look-ahead prediction, deadzones, and boundary limits. camera_shake_trauma.gd Trauma-based camera shake using Perlin noise - industry-standard screenshake implementation. Uses FastNoiseLite for smooth camera shake (squared trauma for feel) with automatic decay. phantom_decoupling.gd Phantom camera pattern: separates "where we look" from "what we follow". Camera follows phantom node, enabling cinematic offsets and area bounds. Camera2D Basics extends Camera2D @ export var target : Node2D @ export var follow_speed := 5.0 func _process ( delta : float ) -> void : if target : global_position = global_position . lerp ( target . global_position , follow_speed * delta ) Position Smoothing extends Camera2D func _ready ( ) -> void :

Built-in smoothing

position_smoothing_enabled

true position_smoothing_speed = 5.0 Camera Limits extends Camera2D func _ready ( ) -> void :

Constrain camera to level bounds

limit_left

0 limit_top = 0 limit_right = 1920 limit_bottom = 1080

Smooth against limits

limit_smoothed

true Camera Shake extends Camera2D var shake_amount := 0.0 var shake_decay := 5.0 func _process ( delta : float ) -> void : if shake_amount

0 : shake_amount = max ( shake_amount - shake_decay * delta , 0 ) offset = Vector2 ( randf_range ( - shake_amount , shake_amount ) , randf_range ( - shake_amount , shake_amount ) ) else : offset = Vector2 . ZERO func shake ( intensity : float ) -> void : shake_amount = intensity

Usage:

$Camera2D . shake ( 10.0 )

Screen shake on explosion

Zoom Controls extends Camera2D @ export var zoom_speed := 0.1 @ export var min_zoom := 0.5 @ export var max_zoom := 2.0 func _unhandled_input ( event : InputEvent ) -> void : if event is InputEventMouseButton : if event . button_index == MOUSE_BUTTON_WHEEL_UP : zoom_in ( ) elif event . button_index == MOUSE_BUTTON_WHEEL_DOWN : zoom_out ( ) func zoom_in ( ) -> void : zoom = zoom . move_toward ( Vector2 . ONE * max_zoom , zoom_speed ) func zoom_out ( ) -> void : zoom = zoom . move_toward ( Vector2 . ONE * min_zoom , zoom_speed ) Look-Ahead Camera extends Camera2D @ export var look_ahead_distance := 50.0 @ export var target : CharacterBody2D func _process ( delta : float ) -> void : if target : var look_ahead := target . velocity . normalized ( ) * look_ahead_distance global_position = target . global_position + look_ahead Split-Screen (Multiple Cameras)

Player 1 Camera

@ onready var cam1 : Camera2D = $Player1 / Camera2D

Player 2 Camera

@ onready var cam2 : Camera2D = $Player2 / Camera2D func _ready ( ) -> void :

Split viewport

cam1 . anchor_mode = Camera2D . ANCHOR_MODE_DRAG_CENTER cam2 . anchor_mode = Camera2D . ANCHOR_MODE_DRAG_CENTER Camera3D Patterns Third-Person Camera extends Camera3D @ export var target : Node3D @ export var distance := 5.0 @ export var height := 2.0 @ export var rotation_speed := 3.0 var rotation_angle := 0.0 func _process ( delta : float ) -> void : if not target : return

Rotate around target

rotation_angle += Input . get_axis ( "camera_left" , "camera_right" ) * rotation_speed * delta

Calculate position

var offset := Vector3 ( sin ( rotation_angle ) * distance , height , cos ( rotation_angle ) * distance ) global_position = target . global_position + offset look_at ( target . global_position , Vector3 . UP ) First-Person Camera extends Camera3D @ export var mouse_sensitivity := 0.002 @ export var max_pitch := deg_to_rad ( 80 ) var pitch := 0.0 func _ready ( ) -> void : Input . mouse_mode = Input . MOUSE_MODE_CAPTURED func _input ( event : InputEvent ) -> void : if event is InputEventMouseMotion :

Yaw (horizontal)

get_parent ( ) . rotate_y ( - event . relative . x * mouse_sensitivity )

Pitch (vertical)

pitch

event . relative . y * mouse_sensitivity pitch = clamp ( pitch , - max_pitch , max_pitch ) rotation . x = pitch Camera Transitions

Smooth camera position change

func move_to_position ( target_pos : Vector2 , duration : float = 1.0 ) -> void : var tween := create_tween ( ) tween . tween_property ( self , "global_position" , target_pos , duration ) tween . set_ease ( Tween . EASE_IN_OUT ) tween . set_trans ( Tween . TRANS_CUBIC ) Cinematic Cameras

Camera path following

extends Path2D @ onready var path_follow : PathFollow2D = $PathFollow2D @ onready var camera : Camera2D = $PathFollow2D / Camera2D func play_cutscene ( duration : float ) -> void : var tween := create_tween ( ) tween . tween_property ( path_follow , "progress_ratio" , 1.0 , duration ) await tween . finished Best Practices 1. One Active Camera

Only one Camera2D should be enabled at a time

Others should have enabled = false

  1. Parent Camera to Player

Scene structure:

Player (CharacterBody2D)

└─ Camera2D

  1. Use Anchors for UI

Camera doesn't affect UI positioned with anchors

UI stays in screen space

  1. Deadzone for Platformers extends Camera2D func _ready ( ) -> void : drag_horizontal_enabled = true drag_vertical_enabled = true drag_left_margin = 0.3 drag_right_margin = 0.3 Reference Godot Docs: Camera2D Godot Docs: Camera3D Related Master Skill: godot-master
返回排行榜