kOS Stock Camera Addon
This project is an addon for kOS, which is a mod for the game Kerbal Space Program. It provides scriptable access to KSP camera controls from KerboScript.
The addon exposes both stock-camera helpers and an optional free-camera mode:
FLIGHTCAMERAcontrols KSP's normal stock flight camera behavior, including camera mode, target, distance, heading, pitch, position, and FOV.MAPCAMERAcontrols map-view camera behavior.INTERNALCAMERAcontrols IVA/internal camera behavior.FREECAMERAtemporarily takes ownership of KSP'sFlightCameraso scripts can set an exact camera pose, including position, facing, roll, anchor behavior, and vessel-relative camera frames.LIGHTcreates a camera-mounted spot light that follows the active gameplay camera, including stock flight camera, free camera, map camera, and IVA when a compatible render camera is available.
The "stock" designation remains important. This addon works with KSP's existing camera systems. Other mods that replace or heavily modify camera behavior may conflict with this functionality.
Existing stock flight-camera usage:
set cam toaddons:camera:flightcamera.
set cam:mode to"FREE".
set cam:fov to45.
set cam:distanceto40.
set cam:headingto90.
set cam:pitch to10.Free-camera usage:
set cam toaddons:camera:freecamera.
set cam:enabledtotrue.
set cam:fov to35.
set cam:anchor toship.
cam:setpose(V(0, 12, -35), heading(90, 10, 0)).
wait 5.
set cam:enabledtofalse.FLIGHTCAMERA and FREECAMERA are intentionally separate. Use
FLIGHTCAMERA for normal stock camera control. Use FREECAMERA when a script
needs full-pose control of the flight camera. Avoid driving both from
one script at the same time.
Camera light usage:
set light toaddons:camera:light.
set light:enabledtotrue.
set light:intensity to1.5.
set light:rangeto80.
set light:angle to45.The root addon is available as:
addons:cameraSuffixes:
| Suffix | Type | Get/Set | Description |
|---|---|---|---|
FLIGHTCAMERA / FLIGHT | FlightCamera | Get | Returns the object which allows control of the stock camera in the flight scene. |
MAPCAMERA / MAP | MapCamera | Get | Returns the object which allows control of the camera in map view. |
INTERNALCAMERA / INTERNAL | InternalCamera | Get | Returns the object which allows control of the IVA/internal camera. |
FREECAMERA / FREE | FreeCamera | Get | Returns the object which allows temporary full-pose control of the flight camera. |
CAMERALIGHT / LIGHT | CameraLight | Get | Returns the object which controls a camera-mounted spot light. |
FLIGHTCAMERA controls KSP's normal flight camera. It does not replace the
stock camera update model; it changes the same fields KSP normally uses.
| Suffix | Type | Get/Set | Description |
|---|---|---|---|
MODECAMERAMODE | String | Get/Set | Returns or changes the selected camera mode. Valid options are "AUTO", "CHASE", "FREE", "LOCKED", and "ORBITAL". |
FOVCAMERAFOV | Scalar | Get/Set | Returns or sets the field of view for the flight camera. |
PITCHCAMERAPITCH | Scalar | Get/Set | Returns or sets the pitch component of the camera position rotation. The actual direction depends on the frame of reference of the current camera mode. |
HEADINGHDGCAMERAHDG | Scalar | Get/Set | Returns or sets the yaw component of the camera position rotation. The actual direction depends on the frame of reference of the current camera mode. |
DISTANCECAMERADISTANCE | Scalar | Get/Set | Returns or sets the distance component of the camera position, the magnitude applied to the rotation defined by pitch and heading. |
POSITIONCAMERAPOSITION | Vector | Get/Set | Returns or sets the camera's position using a CPU-vessel-centered vector. The pitch, heading, and distance components are automatically calculated from the vector. Changing the camera target does not change the reference origin; always set this using vectors based on the CPU vessel. |
TARGET | Part or Vessel | Get/Set | Returns or sets the vessel or part that the camera is pointing at. This is the same as KSP's "Aim here" feature. |
TARGETPOS | Vector | Get | Debugging value. |
PIVOTPOS | Vector | Get | Debugging value. |
POSITIONUPDATER | UserDelegate | Get/Set | A delegate automatically called once per tick to update the camera position. Initially this returns a DONOTHING delegate. Set it back to DONOTHING to stop automatic position updates. |
MAPCAMERA controls the map-view camera.
| Suffix | Type | Get/Set | Description |
|---|---|---|---|
SETFILTER(string, boolean) | Function | � | Sets whether objects of a given type should be visible in map mode. See FILTERNAMES for valid names. |
GETFILTER(string) | Function | � | Returns whether objects of the specified type are visible. See FILTERNAMES for valid names. |
COMMNETMODE | String | Get/Set | Gets or sets the current commnet display mode. See COMMNETNAMES for valid modes. |
PITCHCAMERAPITCH | Scalar | Get/Set | Gets or sets the pitch angle of the camera, relative to the ecliptic plane. |
HDGHEADINGCAMERAHDG | Scalar | Get/Set | Gets or sets the camera heading/yaw. |
DISTANCECAMERADISTANCE | Scalar | Get/Set | Returns the camera distance from the camera pivot, in meters. Map view may enforce limits on this value. |
POSITIONCAMERAPOSITION | Vector | Get/Set | Gets or sets the position of the camera in SHIP-RAW coordinates. The camera will always face toward the pivot point. |
TARGET | Vessel, Body, or Node | Get/Set | Gets or sets the pivot object. |
FILTERNAMES | List | Get | Returns the valid filter names for use with SETFILTER and GETFILTER. |
COMMNETNAMES | List | Get | Returns the valid commnet display mode names for use with COMMNETMODE. |
INTERNALCAMERA controls the IVA/internal camera when IVA is active.
| Suffix | Type | Get/Set | Description |
|---|---|---|---|
PITCHCAMERAPITCH | Scalar | Get/Set | Gets or sets the IVA camera pitch, clamped to the limits of the active internal camera. |
ROTROTATIONCAMERAROTATION | Scalar | Get/Set | Gets or sets the IVA camera rotation, clamped to the limits of the active internal camera. |
FOVCAMERAFOV | Scalar | Get/Set | Gets or sets the IVA camera field of view. |
ACTIVEKERBAL | CrewMember | Get/Set | Gets or sets the active IVA Kerbal. The Kerbal must be on the active vessel. |
ACTIVE | Boolean | Get | True when the current camera mode is IVA. |
FREECAMERA is for scripted full-pose camera control in the flight scene.
Unlike FLIGHTCAMERA, it temporarily takes ownership of KSP's FlightCamera
while enabled, then restores the stock camera when disabled or when KSP changes
to an incompatible camera context.
Access:
set cam toaddons:camera:freecamera.Suffixes:
| Suffix | Type | Get/Set | Description |
|---|---|---|---|
ENABLED | Boolean | Get/Set | Enables or disables free-camera control. Disabling restores the stock flight camera. |
ACTIVE | Boolean | Get | True when FREECAMERA currently owns the flight camera. |
AVAILABLE | Boolean | Get | True when the current scene has a usable FlightCamera. |
STATUS | String | Get | Human-readable status/debug text. |
FOV | Scalar | Get/Set | Camera field of view in degrees. Restored to the stock FOV when freecam is disabled. |
POSITION | Vector | Get/Set | Camera position in SHIP-RAW coordinates. |
DISTANCE | Scalar | Get/Set | Distance from the CPU vessel's CoM. Gets the same value as cam:position:mag; setting scales the current POSITION direction to the requested distance. |
FACING | Direction or Vector | Get/Set | Camera facing. Gets a kOS Direction; accepts a Direction or non-zero Vector look direction when set. Vector assignment uses the camera's body-up vector as the effective up direction. |
HEADINGHDG | Scalar | Get/Set | Local-horizon heading in degrees. 0 is north and 90 is east. |
PITCH | Scalar | Get/Set | Local-horizon pitch in degrees. Positive looks upward. |
ROLL | Scalar | Get/Set | Roll around the camera's forward axis, in degrees. |
ANCHOR | Vessel, Part, Body, or String | Get/Set | Anchor target. Gets the current anchor object; accepts a vessel, part, body, or string shorthand such as "SHIP"/"VESSEL" or "BODY". |
ANCHORFRAME | String | Get/Set | Ship anchor frame. Valid values are "RAW" and "FACING". |
SETPOSE(position, facing) | Function | — | Sets POSITION and FACING together. The facing argument may be a Direction or non-zero Vector look direction. Vector facing uses the body-up vector at the new camera position. |
LOOKAT(targetPosition) | Function | — | Points the camera at a SHIP-RAW target position without moving it. Uses the camera's body-up vector as the effective up direction. |
MOVE(delta) | Function | — | Adds a SHIP-RAW vector delta to POSITION. Equivalent to set cam:position to cam:position + delta. |
COPYFROMSTOCK() | Function | — | Copies the current stock flight camera pose and FOV into freecam state. |
RESET() | Function | — | Resets freecam to the saved stock pose when available. |
ANCHOR controls how the desired camera pose is preserved over time. It accepts
actual kOS target objects as well as string shorthands:
set cam:anchor toship. // vessel anchorset cam:anchor toship:rootpart. // part anchorset cam:anchor tobody. // body anchor, when body is a BodyTargetset cam:anchor to"SHIP". // shorthand for the CPU/active vesselset cam:anchor to"BODY". // shorthand for the CPU/active vessel's bodyWhen anchored to a vessel, the camera follows the vessel center of mass. With
ANCHORFRAME = "RAW", it keeps a fixed raw-axis offset from the vessel. With
ANCHORFRAME = "FACING", it stores both position and facing relative to the
vessel's current facing.
When anchored to a part, the camera position and facing are stored in the part's
local transform space. This is useful for root-part, cockpit, wing, or other
attached cameras because the camera stays fixed relative to the selected part
even when the vessel center of mass shifts due to fuel burn, staging, docking,
or cargo changes. If the part is decoupled or undocked into a new loaded vessel,
the camera continues following that same part. If the part becomes unavailable
because it is destroyed or its vessel unloads, freecam preserves the current
visual pose and falls back to a vessel anchor using the part's vessel when
available, otherwise the CPU vessel. ANCHORFRAME does not change part-anchor
behavior.
When anchored to a body, the camera position is stored in the celestial body's local transform space. This is useful for runway, launchpad, flyby, or terrain-fixed shots. BODY anchors also apply a narrow render-time correction for the active flight camera, re-resolving the body-local pose immediately before rendering to reduce jitter from late floating-origin/Krakensbane corrections.
Changing ANCHOR preserves the current visual/world camera pose, then rebuilds
the internal representation for the new anchor target.
ANCHORFRAME = "RAW" is the default vessel-anchor behavior:
set cam:anchor toship.
set cam:anchorframe to"RAW".
set cam:positiontoV(...).ANCHORFRAME = "FACING" is useful for low-lag onboard, chase, or wing cameras
anchored to a vessel:
set cam:anchor toship.
cam:setpose(ship:facing:starvector*2+ship:facing:vector*-1+ship:facing:topvector*0.1,
ship:facing).
set cam:anchorframe to"FACING".For a camera fixed to a specific part, set the pose and anchor to the part:
cam:setpose(ship:facing:starvector*2+ship:facing:vector*-1+ship:facing:topvector*0.1,
ship:facing).
set cam:anchor toship:rootpart.You can use local-horizon heading, pitch, and roll:
set cam:headingto90.
set cam:pitch to15.
set cam:roll to0.Or assign a kOS Direction, or a non-zero look-direction Vector, directly:
set cam:facingtoship:facing.
set cam:facingtoheading(90, 15, 0).
set cam:facingtoship:facing:vector.When FACING is set from a vector, the vector is treated as a look direction,
not a target position. The camera's effective up direction is the body-up vector
at the camera position, equivalent to:
set cam:facingtolookdirup(<vector>, cam:position-body:position).Use LOOKAT(targetPosition) for point-target behavior. LOOKAT interprets its argument as a SHIP-RAW point, not a look direction:
cam:lookat(target:position).LOOKAT changes facing only; it does not move the camera or change the current anchor settings.
SETPOSE(position, facing) is equivalent to setting POSITION and
FACING, but applies both values as one pose update. The facing argument may
be a Direction or a non-zero Vector look direction. When the facing
argument is a vector, its effective up direction is calculated at the new
position:
cam:setpose(V(0, 12, -35), heading(90, 10, 0)).Use SETPOSE when changing both position and facing in the same script
step.
MOVE(delta) is a shorthand for adding a SHIP-RAW vector to the current camera
position:
cam:move(ship:facing:vector*-5).FREECAMERA controls KSP's existing FlightCamera; it does not create a
separate Unity camera stack.
When KSP changes away from the normal flight camera, freecam releases control.
Map-view transitions may suspend and later resume freecam behavior. IVA/internal
camera mode is treated differently: selecting IVA disables freecam and defers
FlightCamera restore/reparent work until KSP is safely back in flight camera
mode. This avoids corrupting the first IVA camera frame.
The controller normally applies pose updates from LateUpdate. BODY anchors also
re-apply their body-local pose from Camera.onPreCull, but only for the active
flight camera while freecam is active in Flight camera mode. This targeted
render-time correction is intended to keep stationary/body-fixed cameras stable
when KSP performs late floating-origin or Krakensbane corrections.
LIGHT controls a Unity spot light that is kept just behind the active gameplay
camera and pointed the same way as the camera. It is intended as a scriptable
camera-mounted flashlight/fill light for night shots or dark interiors.
Access:
set light toaddons:camera:light.Suffixes:
| Suffix | Type | Get/Set | Description |
|---|---|---|---|
ENABLED | Boolean | Get/Set | Enables or disables the camera light. |
ACTIVE | Boolean | Get | True when the Unity light exists and is currently enabled for a render camera. |
AVAILABLE | Boolean | Get | True when the addon can find a likely gameplay camera to follow. |
STATUS | String | Get | Human-readable status/debug text. |
INTENSITY | Scalar | Get/Set | Unity light intensity. Must be zero or greater. Default is 1. |
RANGEFALLOFF | Scalar | Get/Set | Unity light range in meters; this is the falloff distance. Must be greater than zero. Default is 50. |
ANGLEFOV | Scalar | Get/Set | Spot-light outer cone angle in degrees. Must be greater than 0 and less than 180. Default is 45. |
DISTANCE | Scalar | Get/Set | Distance behind the camera where the light origin is placed. Must be zero or greater. Default is 0.25. |
SHADOWSSHADOW | Boolean | Get/Set | Enables or disables Unity soft shadows for the light. Default is false. |
COLORCOLOUR | RGBA | Get/Set | kOS color structure. Use values like RGB(1, 0.92, 0.82) or WHITE. Alpha is ignored. |
REDR | Scalar | Get/Set | Red color channel from 0 to 1. Default is 1. |
GREENG | Scalar | Get/Set | Green color channel from 0 to 1. Default is 0.92. |
BLUEB | Scalar | Get/Set | Blue color channel from 0 to 1. Default is 0.82. |
The default color is slightly warm white: RGB(1, 0.92, 0.82). Printing addons:camera:light shows a one-line summary of the current light settings.
Example:
set light toaddons:camera:light.
set light:enabledtotrue.
set light:intensity to2.
set light:rangeto100.
set light:angle to35.
set light:distanceto0.5.
set light:color toRGB(1, 0.92, 0.82).
set light:shadows tofalse.You must have an IDE or compiler capable of building Visual Studio solutions
(.sln files). For the sake of simplicity, this repository assumes that it will
be located next to the kOS repository, in the same parent directory. All
references match those of kOS, and use relative paths pointing to the files in
the kOS repository.