RidgeCam
A fixed-angle follow camera for platforming that has to play on a phone, a controller and a keyboard.
RidgeCam
A fixed-angle follow camera for platforming that has to play on a phone, a controller and a keyboard.
The rig holds one heading and never turns. That is the point of it.
CharacterController projects move against the active camera's forward and
right onto the XZ plane, so a camera that never rotates turns camera-relative
movement into absolute screen-direction control: the direction the stick
points is the direction the character travels on screen, from every device, and
no look input is needed to play. A steerable follow camera makes a phone player
manage a second thumb to get anywhere; this one does not.
It follows with damping, and it treats height differently from the ground plane:
- Ground follow is a plain damped chase,
groundDampingseconds to cover ~63% of the gap. - Height follows a stepped anchor. While the subject stays within
heightDeadZonemetres of the anchor the camera holds its level, so a jump moves the character in frame and leaves the world still. Clearing the band — arriving on a new storey — pulls the anchor, and the camera eases up overheightDampingseconds. Without this the frame lurches vertically on every hop, which reads worst on a small screen.
The aim point leads the subject along its own horizontal velocity by
leadDistance, read from CharacterController's velocity telemetry rather than
differenced from position, so the vertical arc of a jump never tilts the shot.
Public fields: follow, offset (where the camera sits relative to the
subject, in world axes), aimHeight, leadDistance, groundDamping,
heightDamping, heightDeadZone.
Attach through Camera.behavior
local cam = entity(rigId).component.get("Camera")
cam.behavior = asset.ref("RidgeCam", "component")
The Camera owns the behavior slot, which is what lets it tell the rig when
follow changes.
Player cameras: leave follow empty
Entering play drops and respawns PlayerPrototype subtrees, so the body is
recreated with a new entity id every time. Set the target on the Camera and
leave this rig's follow empty:
entity(rigId).component.get("Camera").follow = body
PlayerPrototype refreshes Camera.follow to the live body on every clone, and
the rig reads that slot whenever its own follow is empty. Set follow only
for a camera watching a fixed, non-respawning subject.
Choosing the offset
offset sets the viewing angle, and the angle sets how readable depth is. A
steeper drop (a larger y relative to z) reads gaps along the depth axis more
clearly and flattens the sense of height; a shallower one is more dramatic and
makes depth harder to judge. The shipped default, {0, 12, -13}, is a ~42°
look-down: close enough to a 45° isometric that a stick direction and a screen
direction agree, without losing the vertical.
Scoped to this part · feeds back into the world's score.