Camera Systems

作者 gamedev-skillsd4b0e35550c5无许可证1.3K 个星标收录于 2026年10月8日更新于 2026年10月8日仓库11天前更新

Build game cameras that feel good — 2D follow with a deadzone, look-ahead, smoothing, and level-bounds clamping; 3D third-person orbit with collision and first-person look; plus multi-target framing and a shake hook. Engine-neutral techniques that pair with the engine's camera node and rigs like Unity Cinemachine or Godot Camera2D/PhantomCamera. Use when the user mentions camera follow, follow camera, deadzone, look-ahead, camera smoothing, camera bounds/ limits, third-person camera, orbit camera, first-person look, Cinemachine, or camera jitter.

AI 生成的概览

用于构建顺滑的 2D 跟随与 3D 环绕游戏相机的引擎无关技术。

功能
该技能介绍与引擎无关的游戏相机技术:带死区、前瞻和关卡边界限制的 2D 平滑跟随,以及带碰撞推近的 3D 第三人称环绕、第一人称视角、多目标取景和屏幕震动偏移钩子。它提供指导、代码模式和常见陷阱,并将这些技术对应到各引擎的相机节点与装置,如 Unity Cinemachine 或 Godot Camera2D 与 SpringArm3D。它产出的是说明和示例代码,而不是可直接运行的脚本。
适用场景
当 2D 相机需要平滑跟随玩家、保持在关卡内、领先运动或忽略微小移动时使用。用于 3D 第三人称环绕或第一人称视角控制器、多目标取景,或修复相机抖动、跳变、晕动感以及相机显示到关卡边缘之外的问题。
运行要求
不附带脚本,仅为说明性内容。它引用一个可供模型读取的文件 references/follow-and-framing.md。示例面向 Godot 4.7 GDScript 以及带 Cinemachine 3 的 Unity 6.3 LTS,但所述技术被描述为与引擎无关。

Camera systems

The camera is the player's window; bad camera work makes a good game feel awful. This skill covers the engine-neutral camera techniques — smooth follow, deadzones, look-ahead, bounds clamping, third-person orbit with collision, first-person look, and multi-target framing — and maps them onto each engine's camera node or rig.

When to use

  • Use when a 2D camera should follow the player smoothly, stay inside the level, lead the player's motion, or ignore small movements (deadzone).
  • Use when building a 3D third-person orbit camera (mouse/stick look, collision push-in) or a first-person look controller, or framing multiple targets at once.
  • Use to fix camera jitter, snapping, motion sickness, or a camera that shows past the level edge.

When not to use: for the magnitude and trigger of screen shake and impact juice, use game-feel (this skill exposes the shake offset hook it drives). For the engine's concrete camera node/component setup, use godot-3d-essentials (Camera3D, environment) or the engine skill. For player movement itself use the engine movement skill (godot-2d-movement). For performance of many cameras/render targets, see performance-optimization.

Core workflow

  1. Decide what the camera serves. Platformer (lead the jump, see hazards), top-down (center with deadzone), third-person (orbit + collision), first-person (look only). The genre sets the rules.
  2. Follow smoothly and frame-rate independently. Move the camera toward the target with exponential smoothing or a spring (SmoothDamp), not a fixed lerp(a, b, 0.1) — that 0.1 is per-frame and changes with frame rate.
  3. Add a deadzone so tiny target movements don't nudge the camera; it only follows once the target leaves a box/zone. Stops nausea in twitchy games.
  4. Lead the action with look-ahead by offsetting the camera target in the direction of motion or facing, eased in/out so it doesn't whip.
  5. Clamp to level bounds so the camera never shows outside the playable area; combine with smoothing so it eases to a stop at the edge.
  6. For 3D, separate look from collision. Orbit via yaw/pitch on a rig; use a spring arm / ray to pull the camera in when geometry blocks it; clamp pitch.
  7. Update the camera after the target moves. Follow in the late/post step (after movement and physics resolve) to avoid a one-frame lag jitter.
  8. Verify by moving the target at low and high frame rates, into corners and walls, and at the level edges; confirm no jitter, no peeking past bounds, smooth stops. Report what you saw.

Patterns

1. Godot 2D built-in follow: smoothing + bounds (don't hand-roll first)

gdscript
# Godot 4.7 Camera2D. Engine-provided smoothing + hard limits + drag margins.@onready var cam := $Camera2Dfunc _ready() -> void:    cam.make_current()    cam.position_smoothing_enabled = true    cam.position_smoothing_speed = 6.0           # higher = snappier; lower = floatier    cam.limit_left = 0; cam.limit_top = 0        # clamp to the level rect (pixels)    cam.limit_right = level_width; cam.limit_bottom = level_height    cam.drag_horizontal_enabled = true           # built-in deadzone via drag margins

2. Frame-rate-independent smooth follow (when you hand-roll it)

gdscript
# RIGHT: exponential smoothing — same feel at any FPS. `rate` ~ 5..12.func _follow(dt: float) -> void:    var t := 1.0 - exp(-rate * dt)               # converges correctly regardless of dt    global_position = global_position.lerp(target.global_position, t)# WRONG: global_position = global_position.lerp(target.global_position, 0.1)#        → faster smoothing at higher FPS; different feel on every machine.# Unity 6.3 LTS: Vector3.SmoothDamp(transform.position, target.position, ref vel, smoothTime) in# LateUpdate gives the same spring behavior with built-in frame-rate correction.

3. Deadzone + look-ahead (lead the player, ignore jitter)

gdscript
# Camera only chases once the target leaves the deadzone box, then aims AHEAD of motion.func _camera_target(dt: float) -> Vector2:    var to := target.global_position - _focus    var dz := deadzone_half_extents                  # e.g. Vector2(48, 32)    # Only move the focus by the overflow beyond the deadzone (per axis).    _focus.x += clampf(absf(to.x) - dz.x, 0, INF) * signf(to.x)    _focus.y += clampf(absf(to.y) - dz.y, 0, INF) * signf(to.y)    var lead := target.velocity.normalized() * look_ahead_dist    # aim ahead of travel    return _focus + lead

4. 3D third-person orbit with collision push-in

gdscript
# Godot 4.7. Yaw/pitch a pivot; a SpringArm3D auto-pulls the camera in when blocked.func _unhandled_input(e):    if e is InputEventMouseMotion:        _yaw -= e.relative.x * sensitivity        _pitch = clampf(_pitch - e.relative.y * sensitivity, -1.2, 0.4)   # clamp pitch!func _process(_dt):    pivot.rotation = Vector3(_pitch, _yaw, 0)    # $SpringArm3D handles wall collision: set spring_length + collision_mask; the child    # Camera3D slides in automatically. RIGHT: spring arm. WRONG: camera clips through walls.# Unity 6.3 LTS: a Cinemachine 3 CinemachineCamera (namespace Unity.Cinemachine) with an Orbital# Follow + Cinemachine Deoccluder; the CinemachineBrain on the Camera blends automatically.

5. Screen shake hook (owned trigger lives in game-feel)

gdscript
# Expose an additive offset the game-feel trauma model writes to; follow + shake compose.var shake_offset := Vector2.ZERO                 # set each frame by game-feel (trauma^2 * noise)func _apply(final_focus: Vector2) -> void:    global_position = final_focus + shake_offset  # shake rides ON TOP of smooth follow# Unity Cinemachine: add a CinemachineBasicMultiChannelPerlin and set amplitude from trauma.

Pitfalls

  • lerp(pos, target, const) per frame is frame-rate dependent — floatier at 30 FPS, snappier at 144. Use 1 - exp(-rate*dt) or SmoothDamp.
  • Following in the normal update before the target has moved yields a one-frame lag jitter. Follow in LateUpdate / after movement/physics resolve.
  • No bounds clamp lets the camera show black past the level edge. Clamp focus to the level rect (account for the viewport half-size so the view, not the center, stays inside).
  • No deadzone in twitchy games makes the camera twitch with every micro-movement → nausea.
  • Unclamped pitch in third/first-person flips the camera over the top. Clamp pitch to ~±80°.
  • Camera clipping through walls in 3D — use a spring arm / occlusion ray to pull in.
  • Snapping on teleport/respawn is jarring; either hard-cut intentionally (and reset smoothing) or fast-ease. Don't let a huge SmoothDamp distance whip across the level.
  • Shake driving the follow target instead of an additive offset makes follow fight shake. Compose: smooth follow first, add shake offset last.
  • Per-axis vs radial deadzone confusion — a box deadzone feels different from a circular one; pick deliberately.

References

  • For the exponential-smoothing/spring derivation, a complete deadzone+look-ahead+bounds 2D rig, 3D spring-arm/orbit details, first-person look, multi-target/group framing and split-screen, cinematic camera blends, and the Cinemachine 3 / Godot Camera2D / PhantomCamera mapping, read references/follow-and-framing.md.

Related skills

  • game-feel — owns screen-shake trauma/triggers; this skill exposes the offset it writes.
  • godot-2d-movement, godot-3d-essentials — the player/world the camera frames; Camera3D setup.
  • physics-tuning — interpolate camera follow with the physics step to kill jitter.
  • platformer, fps-shooter — genres whose camera rules this skill implements.
  • performance-optimization — cost of extra cameras, render targets, and split-screen.

来源与署名

来源:gamedev-skills/awesome-gamedev-agent-skills位于skills/disciplines/camera-systems提交d4b0e35

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架