Skip to content
Development
Skill

/phantom-camera

Use when using the Phantom Camera addon — PhantomCamera2D/3D with priority-based switching, follow and look-at modes, and tween transitions

From plugin
godot-prompter
54157 skills9 agents1 hook
Install
$ npx -y skills add jame581/GodotPrompter --skill phantom-camera --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/phantom-camera

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when using the Phantom Camera addon — PhantomCamera2D/3D with priority-based switching, follow and look-at modes, and tween transitions

SKILL.md

phantom-camera.SKILL.md
name: phantom-camera
description: Use when using the Phantom Camera addon — PhantomCamera2D/3D with priority-based switching, follow and look-at modes, and tween transitions

Phantom Camera

> **Related skills:** **camera-system** for hand-rolled camera patterns, **tween-animation** for the easing concepts the transitions build on.

> **Addon:** Phantom Camera · version `v0.11.0.2` · Godot 4.4+ · MIT · source: https://github.com/ramokz/phantom-camera · nodes are GDScript, plus an official C# wrapper API (`namespace PhantomCamera`) shipped as source `.cs` files in the addon. **Pre-1.0:** minor versions may break API.

---

1. When to use Phantom Camera vs. `camera-system`

| Approach | Best for | |---|---| | Hand-rolled (`camera-system` skill) | One camera, simple follow/shake, no addon dependency | | **Phantom Camera** | Multiple camera "shots" that need priority-based switching, dead-zone/group/path/third-person follow logic, and smooth resource-driven tweens between them — Cinemachine-style workflow |

Reach for Phantom Camera when a scene needs several distinct camera behaviors (gameplay follow, a cutscene framing, a boss-fight group shot) that swap automatically based on priority, rather than one script juggling every case. It replaces the `Camera2D`/`Camera3D` positioning logic itself — you still keep exactly one real `Camera2D`/`Camera3D` per viewport; Phantom Camera nodes never render anything on their own.

---

2. Install & setup

**Asset Library (recommended):** Godot AssetLib → search "Phantom Camera" → Download (select only the `phantom_camera` directory) → **Project → Project Settings → Plugins** → enable it.

**GitHub zip:** extract `addons/phantom_camera/` into the project root, then enable the plugin the same way.

Enabling the plugin auto-registers a `PhantomCameraManager` autoload singleton and **restarts the editor every time `_enable_plugin()` runs** (not just the first time) — expected behavior, not a bug. No manual autoload setup is needed. Six custom node types become available in the "Create New Node" dialog: `PhantomCamera2D`, `PhantomCamera3D`, `PhantomCameraHost`, `PhantomCameraNoiseEmitter2D`, `PhantomCameraNoiseEmitter3D`, and `PhantomCameraTweenDirector`.

**C# projects:** the addon ships its official wrapper as plain `.cs` source files under `addons/phantom_camera/scripts/**` (`namespace PhantomCamera`) — no NuGet package to add. A C#-enabled Godot project (one with its own generated `.csproj`, `Godot.NET.Sdk`) picks these up automatically once the addon folder is present; `using PhantomCamera;` is then enough (§3–§7).

---

3. Host + camera model

Two node kinds work together:

  • **`PhantomCameraHost`** — add it **as a child of your real `Camera2D`/`Camera3D`** (not the other way

around). It reads the highest-priority `PhantomCamera2D`/`3D` in the scene and drives the real camera's transform every frame. Only the first `PhantomCameraHost` child of a given camera is used.

  • **`PhantomCamera2D`** / **`PhantomCamera3D`** — placed anywhere else in the scene tree (siblings of

the player, inside trigger areas, cutscene rigs). Any number can exist; each one describes a candidate "shot" via `priority`, a follow mode, and (3D only) a look-at mode. They render nothing themselves.

# Scene tree:
# Camera2D (or Camera3D)
#   └─ PhantomCameraHost
# Player (CharacterBody2D)
#   └─ PhantomCamera2D   (priority 0, follow_mode = SIMPLE, follow_target = Player)
# BossArena
#   └─ PhantomCamera2D   (priority 10, follow_mode = GROUP, follow_targets = [Player, Boss])
# CameraRig.gd — on the Camera2D/Camera3D
extends Camera2D

@onready var host: PhantomCameraHost = $PhantomCameraHost

func _ready() -> void:
    # host.camera_2d / host.camera_3d are populated automatically from get_parent()
    var active := host.get_active_pcam()
    print("Active PCam: ", active.name if active else "none")
// CameraRig.cs — on the Camera2D/Camera3D
using PhantomCamera;

public partial class CameraRig : Camera2D
{
    private PhantomCameraHost _host;

    public override void _Ready()
    {
        // Host.Camera2D / Host.Camera3D are populated automatically from GetParent()
        _host = GetNode<Node>("PhantomCameraHost").AsPhantomCameraHost();
        var active = _host.GetActivePhantomCamera();
        GD.Print("Active PCam: ", active is PhantomCamera2D p ? p.Node2D.Name.ToString() : "none");
    }
}

`PhantomCameraHost.interpolation_mode` (C#: `InterpolationMode`, enum `Auto`/`Idle`/`Physics`/`Manual`) controls when the Host updates the real camera: `AUTO` (default — picks physics or idle based on the active PCam's target), `IDLE`, `PHYSICS`, or `MANUAL` (call `host.process(delta)` yourself each tick).

`host_layers` (`@export_flags_2d_render` / `_3d_render`) on both the Host and each PCam gate which PCams a given Host will consider — a PCam is only eligible if its `host_layers` bitmask overlaps the Host's.

---

4. Priority-based switching

Every `PhantomCamera2D`/`3D` has `priority: int = 0`. The `PhantomCameraHost` attached to the scene's real camera always follows the highest-priority PCam that shares a `host_layers` bit with it. Change `priority` at runtime with `set_priority(value)` / read with `get_priority()` — values are clamped to `>= 0`.

# TriggerArea.gd — raise priority while the player is inside, restore on exit
extends Area2D

@export var area_pcam: PhantomCamera2D

func _ready() -> void:
    area_entered.connect(_on_entered)
    area_exited.connect(_on_exited)

func _on_entered(area: Area2D) -> void:
    if area.get_parent() is CharacterBody2D:
        area_pcam.set_priority(20)

func _on_exited(area: Area2D) -> void:
    if area.get_parent() is CharacterBody2D:
        area_pcam.set_priority(0)
using PhantomCamera;

public partial class TriggerArea : Area2D
{
    [Export] private Node2D _areaPCamNode;
    private PhantomCamera2D _areaPCam;

    public override void _Rea
Read more
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

Get the whole plugin