roblox-camera
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWhen to Load
加载时机
Load when scripting custom camera behavior (cutscenes, third-person follow, custom rotation), manipulating for placement/rotation, raycasting from the screen, or building a non-default player view. Client-only.
CFrame在编写自定义相机行为(过场动画、第三人称跟随、自定义旋转)、操控进行位置/旋转调整、从屏幕发射射线,或构建非默认玩家视角时加载。仅客户端可用。
CFrameQuick Reference
快速参考
The Camera: — one per client. Set to disable defaults and take full control. Without it, defaults overwrite your CFrame every frame.
workspace.CurrentCameraCameraType = ScriptableCameraType: , /// (subject-following), (default), (no default), (fixed Y, rotates around player). cannot be — setting it reverts.
FixedAttachWatchTrackFollowCustomScriptableOrbitalCameraSubjectnilKey properties: , , (deg), (/), , , , , .
CFrameCameraSubjectFieldOfViewFieldOfViewModeVerticalDiagonalNearPlaneZViewportSizeHeadLockedHeadScaleFocusCFrame essentials:
luau
CFrame.new(pos)
CFrame.lookAt(at, lookAt, up?) -- preferred over deprecated CFrame.new(pos, lookAt)
CFrame.Angles(rx, ry, rz) -- XYZ Euler (radians)
cf * Vector3.new(0, 0, 10) -- local offset → world
cf:Lerp(goal, alpha) -- 0..1 linear interp
cf.LookVector / RightVector / UpVector -- world-space unit axesCustom camera loop — always , never :
RenderSteppedHeartbeatluau
camera.CameraType = Enum.CameraType.Scriptable
RunService.RenderStepped: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: (accounts for GUI inset) vs (raw, NO inset). returns a unit Ray (1 stud) — multiply by length for actual raycast.
camera:ScreenPointToRay(mx, my)camera:ViewportPointToRay(mx, my)ScreenPointToRayDirectionPitfalls:
- Client-only. Server sets silently dropped.
- Without , defaults overwrite your CFrame every frame.
Scriptable - for camera (visual sync).
RenderSteppedadds 1-frame lag.Heartbeat - lacks VR head rotation — use
Camera.CFramefor true view.GetRenderCFrame() - is outdated — apply roll via
SetRollon CFrame.CFrame.Angles(0, 0, roll) - reverts to previous.
CameraSubject = nil - is legacy (back-compat only) — use
CFrame.new(pos, lookAt)for new code.CFrame.lookAt(at, lookAt) - ≠
ScreenPointToRay(GUI inset). UseViewportPointToRayfor mouse input.ScreenPointToRay
See for first/third-person recipes, cutscenes, screen shake, mouse-look, full API.
references/full.md相机: — 每个客户端一个实例。将设置为可禁用默认行为,获得完全控制权。若不设置,默认行为会每帧覆盖你的CFrame设置。
workspace.CurrentCameraCameraTypeScriptableCameraType枚举:、///(跟随目标)、(默认)、(无默认行为)、(Y轴固定,围绕玩家旋转)。不能设为 — 设置为会恢复之前的设置。
FixedAttachWatchTrackFollowCustomScriptableOrbitalCameraSubjectnilnil关键属性:、、(度数)、(/)、、、、、。
CFrameCameraSubjectFieldOfViewFieldOfViewModeVerticalDiagonalNearPlaneZViewportSizeHeadLockedHeadScaleFocusCFrame核心用法:
luau
CFrame.new(pos)
CFrame.lookAt(at, lookAt, up?) -- 优先使用此方法,替代已弃用的CFrame.new(pos, lookAt)
CFrame.Angles(rx, ry, rz) -- XYZ欧拉角(弧度)
cf * Vector3.new(0, 0, 10) -- 本地偏移 → 世界坐标
cf:Lerp(goal, alpha) -- 0到1之间的线性插值
cf.LookVector / RightVector / UpVector -- 世界空间单位轴向量自定义相机循环 — 务必使用,绝不要用:
RenderSteppedHeartbeatluau
camera.CameraType = Enum.CameraType.Scriptable
RunService.RenderStepped:Connect(function(dt)
local desired = CFrame.lookAt(head.Position - offset, head.Position)
camera.CFrame = camera.CFrame:Lerp(desired, math.min(dt * 10, 1))
end)从相机发射射线:(考虑GUI内边距) vs (原始坐标,不考虑内边距)。返回单位射线(1 studs)—— 需将乘以长度以获得实际射线。
camera:ScreenPointToRay(mx, my)camera:ViewportPointToRay(mx, my)ScreenPointToRayDirection注意事项:
- 仅客户端可用。服务器端设置会被静默丢弃。
- 若未设置,默认行为会每帧覆盖你的CFrame设置。
Scriptable - 相机需使用(视觉同步)。使用
RenderStepped会增加1帧延迟。Heartbeat - 不包含VR头部旋转 — 需使用
Camera.CFrame获取真实视角。GetRenderCFrame() - 已过时 — 需通过在CFrame上应用
SetRoll来设置旋转。CFrame.Angles(0, 0, roll) - 会恢复之前的设置。
CameraSubject = nil - 为旧版方法(仅用于向后兼容)—— 新代码请使用
CFrame.new(pos, lookAt)。CFrame.lookAt(at, lookAt) - ≠
ScreenPointToRay(区别在于是否考虑GUI内边距)。鼠标输入请使用ViewportPointToRay。ScreenPointToRay
更多第一/第三人称实现方案、过场动画、屏幕震动、鼠标视角控制及完整API,请查看。
references/full.md