| id | camerasystem |
|---|---|
| title | Camera System |
| sidebar_position | 10 |
This document explains how to move, rotate, and control cameras using the APIs in CameraSystem.swift.
For gameplay, always use the game camera (not the editor/scene camera). Call findGameCamera() and make it active:
let camera = findGameCamera()
CameraSystem.shared.activeCamera = cameraIf no game camera exists, findGameCamera() creates one and sets it up with default values.
Use absolute or relative movement:
// Absolute position
moveCameraTo(entityId: camera, 0.0, 3.0, 7.0)
// Relative movement in camera local space
cameraMoveBy(entityId: camera, delta: simd_float3(0.0, 0.0, -1.0), space: .local)
// Relative movement in world space
cameraMoveBy(entityId: camera, delta: simd_float3(1.0, 0.0, 0.0), space: .world)Use rotateCamera for pitch/yaw rotation, or cameraLookAt to aim at a target.
// Rotate by pitch/yaw (radians), with optional sensitivity
rotateCamera(entityId: camera, pitch: 0.02, yaw: 0.01, sensitivity: 1.0)
// Look-at orientation
cameraLookAt(
entityId: camera,
eye: simd_float3(0.0, 3.0, 7.0),
target: simd_float3(0.0, 0.0, 0.0),
up: simd_float3(0.0, 1.0, 0.0)
)Follow a target entity with a fixed offset. You can optionally smooth the motion.
let target = findEntity(name: "player") ?? createEntity()
let offset = simd_float3(0.0, 2.0, 6.0)
// Instant follow
cameraFollow(entityId: camera, targetEntity: target, offset: offset)
// Smoothed follow
cameraFollow(entityId: camera, targetEntity: target, offset: offset, smoothFactor: 6.0, deltaTime: deltaTime)cameraFollowDeadZone only moves the camera when the target leaves a box around it. This is useful for platformers and shoulder cameras.
let deadZone = simd_float3(1.0, 0.5, 1.0)
cameraFollowDeadZone(
entityId: camera,
targetEntity: target,
offset: offset,
deadZoneExtents: deadZone,
smoothFactor: 6.0,
deltaTime: deltaTime
)The camera path system moves the active camera through a sequence of waypoints with smooth interpolation.
let waypoints = [
CameraWaypoint(
position: simd_float3(0, 5, 10),
rotation: simd_quatf(angle: 0, axis: simd_float3(0, 1, 0)),
segmentDuration: 2.0
),
CameraWaypoint(
position: simd_float3(10, 5, 10),
rotation: simd_quatf(angle: Float.pi / 4, axis: simd_float3(0, 1, 0)),
segmentDuration: 2.0
)
]
startCameraPath(waypoints: waypoints, mode: .once)You can also build waypoints that look at a target:
let waypoint = CameraWaypoint(
position: simd_float3(0, 5, 10),
lookAt: simd_float3(0, 0, 0),
up: simd_float3(0, 1, 0),
segmentDuration: 2.0
)Call updateCameraPath(deltaTime:) from your main update loop:
func update(deltaTime: Float) {
updateCameraPath(deltaTime: deltaTime)
}startCameraPath(waypoints: waypoints, mode: .loop)
let settings = CameraPathSettings(startImmediately: true) {
print("Camera path completed")
}
startCameraPath(waypoints: waypoints, mode: .once, settings: settings)startCameraPathandupdateCameraPathoperate onCameraSystem.shared.activeCamera.segmentDurationis the time to move from the current waypoint to the next.- For gameplay, always acquire the camera with
findGameCamera()and set it active before path playback or follow logic.