roblox-camera — Claude Code skill for Roblox cameras
A skill for scripting Roblox camera behavior: CFrame placement, screen raycasts, first and third person, cutscenes. Useful when the camera jitters or clips through walls.
npx skills add TabooHarmony/roblox-brain --skill roblox-camera -a claude-codeWhat roblox-camera does
The skill loads when you write or fix camera behavior in Roblox: placement with CFrame, raycasts from a screen point, switching between first and third person, shoulder views, cutscenes. Inside is a quick reference for workspace.CurrentCamera, the CameraType enum and properties like FieldOfView and CameraSubject, plus a Luau table of CFrame operations.
There is a pitfalls section too. Without CameraType = Scriptable the defaults overwrite your CFrame every frame, and camera motion belongs in PreRender because Heartbeat adds a frame of lag. ScreenPointToRay accounts for the GUI inset, ViewportPointToRay does not. All of it is client-side: a CFrame set on the server is silently dropped.
A references/full.md file holds recipes for first and third person, cutscenes, screen shake and mouse-look. The skill runs on every listed platform, but you still verify the code in Roblox Studio itself — the skill does not track engine version differences.
What it helps with
- build a third-person camera that follows the character smoothly
- fix camera jitter while the player moves
- stop the camera from clipping through walls
- set up a cutscene that flies around the map
- raycast from the point under the cursor
Example prompts for the agent
- Write a third-person Roblox camera that follows the head via PreRender and Lerp
- The camera jitters when I sprint — look at my script and fix it
- Build a cutscene flying over spawn, camera should be Scriptable
How to install roblox-camera
1Skills CLI (Vercel)
npx skills add TabooHarmony/roblox-brain --skill roblox-camera -a claude-code2Manually: put the files in place
~/.claude/skills/roblox-camera/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/roblox-camera/
1Skills CLI (Vercel)
npx skills add TabooHarmony/roblox-brain --skill roblox-camera -a codex2Manually: put the files in place
.agents/skills/roblox-camera/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add TabooHarmony/roblox-brain --skill roblox-camera -a cursor2Manually: put the files in place
.cursor/skills/roblox-camera/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install TabooHarmony/roblox-brain roblox-camera2Manually: put the files in place
.github/skills/roblox-camera/SKILL.md1Skills CLI (Vercel)
npx skills add TabooHarmony/roblox-brain --skill roblox-camera -a gemini-cli2Platform CLI
gemini skills install https://github.com/TabooHarmony/roblox-brain --path skills/gameplay/roblox-cameraManually: put the files in place
.devin/skills/roblox-camera/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add TabooHarmony/roblox-brain --skill roblox-camera -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about roblox-camera
How do I install roblox-camera in Claude?
Run npx skills add TabooHarmony/roblox-brain --skill roblox-camera -a claude-code. The skill lands in ~/.claude/skills/roblox-camera/SKILL.md.
What does roblox-camera do?
It gives the agent a Roblox camera reference: CFrame, CameraType, screen raycasts and pitfalls such as defaults overwriting your CFrame. It also covers first and third person, cutscenes and screen shake.
Why does my camera ignore the CFrame I set?
You probably have not set CameraType = Scriptable. Without it the default behavior overwrites your CFrame every frame.
Source text
SKILL.md · MIT
---
name: roblox-camera
description: "Use when scripting or fixing Roblox camera behavior: CFrame placement, screen raycasts, first/third-person, shoulder views, cutscenes."
when_to_use: "Also when the camera clips through walls, jitters, aims wrong on touch or gamepad, or needs a death cam or spectate view."
last_reviewed: 2026-10-14
sources:
- https://create.roblox.com/docs/reference/engine/classes/Camera
- https://create.roblox.com/docs/reference/engine/enums/CameraType
- https://create.roblox.com/docs/reference/engine/datatypes/CFrame
- original
- https://raw.githubusercontent.com/Roblox/creator-docs/main/content/en-us/reference/engine/classes/WorldRoot.yaml
---
# Roblox Camera
## When to Load
Load when scripting custom camera behavior (cutscenes, third-person follow, custom rotation), manipulating `CFrame` for placement/rotation, raycasting from the screen, or building a non-default player view. Client-only.
## Quick Reference
**The Camera**: `workspace.CurrentCamera`: one per client. Set `CameraType = Scriptable` to disable defaults and take full control. Without it, defaults overwrite your CFrame every frame.
**CameraType**: `Fixed`, `Attach`/`Watch`/`Track`/`Follow` (subject-following), `Custom` (default), `Scriptable` (no default), `Orbital` (fixed Y, rotates around player). `CameraSubject` cannot be `nil`: setting it reverts.
**Key properties**: `CFrame`, `CameraSubject`, `FieldOfView` (deg), `FieldOfViewMode` (`Vertical`/`Diagonal`), `NearPlaneZ`, `ViewportSize`, `HeadLocked`, `HeadScale`, `Focus`.
**CFrame essentials**:
| Operation | Luau |
| --- | --- |
| Position only | `CFrame.new(position)` |
| Look at target | `CFrame.lookAt(position, target, upVector)` |
| XYZ rotation | `CFrame.Angles(rx, ry, rz)` |
| Local to world | `cf * Vector3.new(0, 0, 10)` |
| Interpolate | `cf:Lerp(goal, alpha)` |
| Unit axes | `cf.LookVector`, `cf.RightVector`, `cf.UpVector` |
**Custom camera loop**: always `PreRender`, never `Heartbeat`:
```luau
camera.CameraType = Enum.CameraType.Scriptable
RunService.PreRender:Connect(function(dt)
local desired = CFrame.lookAt(head.Position - offset, head.Position)
camera.CFrame = camera.CFrame:Lerp(desired, math.min(dt * 10, 1))
end)
```
**Raycasting from camera**: `camera:ScreenPointToRay(mx, my)` (accounts for GUI inset) vs `camera:ViewportPointToRay(mx, my)` (raw, NO inset). `ScreenPointToRay` returns a unit Ray (1 stud); multiply `Direction` by length for the actual raycast.
**Pitfalls**:
- Client-only. Server sets silently dropped.
- Without `Scriptable`, defaults overwrite your CFrame every frame.
- `PreRender` for camera (visual sync). `Heartbeat` adds 1-frame lag. `RenderStepped` still works but is superseded by `PreRender`.
- `Camera.CFrame` lacks VR head rotation; use `GetRenderCFrame()` for the true view.
- `SetRoll` is outdated; apply roll via `CFrame.Angles(0, 0, roll)` on CFrame.
- `CFrame.new(pos, lookAt)` is legacy (back-compat only); use `CFrame.lookAt(at, lookAt)` for new code.
See `references/full.md` for first/third-person recipes, cutscenes, screen shake, mouse-look, full API.
© TabooHarmony · MIT · TabooHarmony/roblox-brain