Skip to content

Inspector Camera Controller

Summary#

The InspectorCameraController orbits a camera around a Target location on a sphere defined by Yaw and Pitch angles, always pointing at the target. This is useful for "model viewer" or "inspector" style cameras that allow a user to inspect an object from any angle.

  • Adjusting Yaw rotates the camera around the target;
  • Adjusting Pitch tilts the camera up or down relative to the target;
  • Adjusting Distance moves the camera toward or away from the target.

Example Usage#

// One time setup:
var controller = camera.CreateController<InspectorCameraController>(); // (1)!
controller.Target = Location.Origin; // (2)!
controller.WorldUp = Direction.Up; // (3)!

// Per-frame:
controller.AdjustAllViaDefaultControls(input.KeyboardAndMouse, deltaTime); // (4)!
controller.AdjustAllViaDefaultControls(input.GameControllersCombined, deltaTime); // (5)!
controller.Progress(deltaTime); // (6)!
  1. This creates the controller, attached to the given camera.
  2. This sets the location the camera will orbit around (and always look at).
  3. This sets which way is "up" — the axis the camera yaws around, and the reference for what "up" means when tilting via Pitch.

  4. This manipulates the camera according to the default keyboard and mouse scheme. The yaw/pitch/distance properties will change according to any registered user inputs for this frame.

    You can replace this with more specific control code if desired (see below); or remove it entirely if you do not wish to allow user keyboard/mouse input control.

  5. This manipulates the camera according to the default game controller scheme for all game controllers combined. The yaw/pitch/distance properties will change according to any registered user inputs for this frame.

    You can replace this with more specific control code if desired (see below); or remove it entirely if you do not wish to allow user gamepad input control.

  6. Calling Progress() once per frame is required on all camera controllers in order for them to actually alter their target Camera's parameters.

Properties#

Per-Frame Targets#

Yaw

Sets how far around the target the camera has rotated, around the WorldUp axis.

Increasing this value turns the camera clockwise around the target; decreasing turns anticlockwise.

Defaults to .

Pitch

Sets how high or low the camera is tilted relative to the target.

A value of places the camera level with the target on the horizontal plane; positive values tilt upward, negative values tilt downward.

By default, this value is automatically clamped to ±90° during Progress() so that the camera never flips upside-down. Set AllowUpsideDownFlip to true to disable this behavior.

Defaults to .

Distance

Sets how far from the Target the camera is.

This value will be clamped between MinDistance and MaxDistance when either are non-null.

Defaults to 0.6f.

Configuration#

Target

The location in the world that the camera is orbiting around, and always looking at.

Defaults to Location.Origin.

WorldUp

The world's "up" direction. The camera yaws around this axis, and Pitch is interpreted relative to it.

Defaults to Direction.Up.

AllowUpsideDownFlip

When false (the default), Pitch is automatically clamped to ±90° each frame so the camera never tilts past straight-up or straight-down.

When true, no such clamp is applied — the camera is free to flip upside-down.

Defaults to false.


MinDistance

The minimum permitted value for Distance. Can be null to remove the lower bound.

Defaults to 0.6f.

MaxDistance

The maximum permitted value for Distance. Can be null to remove the upper bound.

Defaults to 2f.

Reacting to Input#

As camera controllers are often meant to be affected by user input, there are some convenience methods supplied for controlling the primary per-frame target properties:

Adjusting Pitch#

Keyboard / Mouse#

AdjustPitchViaMouseCursor(...)

Adjusts Pitch according to the captured mouse cursor movement for this frame.

The axis sets which cursor movement direction will be used (defaults to Y, e.g. up/down).

The adjustmentPerPixel value is the angle to add to Pitch for each pixel moved according to the given axis. If null, DefaultPitchSensitivityMouseCursor will be used.

If invertMouseControl is true, the calculated adjustment will be reversed.

AdjustPitchViaMouseWheel(...)

Adjusts Pitch according to the captured mouse wheel movement for this frame.

The adjustmentPerWheelIncrement value is the angle to add to Pitch for each scroll increment on the mouse wheel. If null, DefaultPitchSensitivityMouseWheel will be used.

If invertMouseControl is true, the calculated adjustment will be reversed.

AdjustPitchViaKeyPress(...)

Adjusts Pitch according to whether a certain key is depressed for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The keyToTestFor is the key that, when pressed, will adjust this property.

If reverse is true, the calculated adjustment will be reversed. Defaults to false. This parameter lets you specify two keys in a pair that mirror each other by invoking this method twice (once with reverse as false and once with reverse as true).

The adjustmentPerSec value is the angle to add to Pitch for each second this key is depressed. If null, DefaultPitchSensitivityKeyOrButtonPress will be used.

Gamepad#

AdjustPitchViaControllerStick(...)

Adjusts Pitch according to the captured controller stick position for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The axis sets which stick movement direction will be used (defaults to Y, e.g. up/down).

The maxAdjustmentPerSec value is the angle to add to Pitch when the stick is fully displaced along the given axis. If null, DefaultPitchSensitivityControllerStick will be used.

If useLeftStick is true, the left controller stick will be measured; otherwise the right stick will be measured. Defaults to false.

If invertStickControl is true, the calculated adjustment will be reversed.

AdjustPitchViaControllerTriggers(...)

Adjusts Pitch according to the captured controller trigger positions for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The maxAdjustmentPerSec value is the angle to add to Pitch when the trigger is fully displaced. If null, DefaultPitchSensitivityControllerTrigger will be used.

If leftTriggerPitchesUp is true, the left trigger will pitch up and the right trigger pitch down; otherwise these directions will be reversed. Defaults to true.

AdjustPitchViaButtonPress(...)

Adjusts Pitch according to whether a certain button is depressed for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The buttonToTestFor is the button that, when pressed, will adjust this property.

If reverse is true, the calculated adjustment will be reversed. Defaults to false. This parameter lets you specify two buttons in a pair that mirror each other by invoking this method twice (once with reverse as false and once with reverse as true).

The adjustmentPerSec value is the angle to add to Pitch for each second this button is depressed. If null, DefaultPitchSensitivityKeyOrButtonPress will be used.

Other#

AdjustPitch(...)

Adjusts Pitch according to the given turn rate (adjustmentPerSec) and time step (deltaTime).

This method does not inspect any user input data but is provided as a convenience for building custom per-frame control code.

Adjusting Yaw#

Keyboard / Mouse#

AdjustYawViaMouseCursor(...)

Adjusts Yaw according to the captured mouse cursor movement for this frame.

The axis sets which cursor movement direction will be used (defaults to X, e.g. left/right).

The adjustmentPerPixel value is the angle to add to Yaw for each pixel moved according to the given axis. If null, DefaultYawSensitivityMouseCursor will be used.

If invertMouseControl is true, the calculated adjustment will be reversed.

AdjustYawViaMouseWheel(...)

Adjusts Yaw according to the captured mouse wheel movement for this frame.

The adjustmentPerWheelIncrement value is the angle to add to Yaw for each scroll increment on the mouse wheel. If null, DefaultYawSensitivityMouseWheel will be used.

If invertMouseControl is true, the calculated adjustment will be reversed.

AdjustYawViaKeyPress(...)

Adjusts Yaw according to whether a certain key is depressed for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The keyToTestFor is the key that, when pressed, will adjust this property.

If reverse is true, the calculated adjustment will be reversed. Defaults to false. This parameter lets you specify two keys in a pair that mirror each other by invoking this method twice (once with reverse as false and once with reverse as true).

The adjustmentPerSec value is the angle to add to Yaw for each second this key is depressed. If null, DefaultYawSensitivityKeyOrButtonPress will be used.

Gamepad#

AdjustYawViaControllerStick(...)

Adjusts Yaw according to the captured controller stick position for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The axis sets which stick movement direction will be used (defaults to X, e.g. left/right).

The maxAdjustmentPerSec value is the angle to add to Yaw when the stick is fully displaced along the given axis. If null, DefaultYawSensitivityControllerStick will be used.

If useLeftStick is true, the left controller stick will be measured; otherwise the right stick will be measured. Defaults to false.

If invertStickControl is true, the calculated adjustment will be reversed.

AdjustYawViaControllerTriggers(...)

Adjusts Yaw according to the captured controller trigger positions for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The maxAdjustmentPerSec value is the angle to add to Yaw when the trigger is fully displaced. If null, DefaultYawSensitivityControllerTrigger will be used.

If leftTriggerYawsClockwise is true, the left trigger will yaw anticlockwise and the right trigger yaw clockwise; otherwise these directions will be reversed. Defaults to true.

AdjustYawViaButtonPress(...)

Adjusts Yaw according to whether a certain button is depressed for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The buttonToTestFor is the button that, when pressed, will adjust this property.

If reverse is true, the calculated adjustment will be reversed. Defaults to false. This parameter lets you specify two buttons in a pair that mirror each other by invoking this method twice (once with reverse as false and once with reverse as true).

The adjustmentPerSec value is the angle to add to Yaw for each second this button is depressed. If null, DefaultYawSensitivityKeyOrButtonPress will be used.

Other#

AdjustYaw(...)

Adjusts Yaw according to the given turn rate (adjustmentPerSec) and time step (deltaTime).

This method does not inspect any user input data but is provided as a convenience for building custom per-frame control code.

Adjusting Distance#

Keyboard / Mouse#

AdjustDistanceViaMouseCursor(...)

Adjusts Distance according to the captured mouse cursor movement for this frame.

The axis sets which cursor movement direction will be used (defaults to Y, e.g. up/down).

The adjustmentPerPixel value is the amount to add to Distance for each pixel moved according to the given axis. If null, DefaultDistanceSensitivityMouseCursor will be used.

If invertMouseControl is true, the calculated adjustment will be reversed.

AdjustDistanceViaMouseWheel(...)

Adjusts Distance according to the captured mouse wheel movement for this frame.

The adjustmentPerWheelIncrement value is the amount to add to Distance for each scroll increment on the mouse wheel. If null, DefaultDistanceSensitivityMouseWheel will be used.

If invertMouseControl is true, the calculated adjustment will be reversed.

AdjustDistanceViaKeyPress(...)

Adjusts Distance according to whether a certain key is depressed for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The keyToTestFor is the key that, when pressed, will adjust this property.

If reverse is true, the calculated adjustment will be reversed. Defaults to false. This parameter lets you specify two keys in a pair that mirror each other by invoking this method twice (once with reverse as false and once with reverse as true).

The adjustmentPerSec value is the amount to add to Distance for each second this key is depressed. If null, DefaultDistanceSensitivityKeyOrButtonPress will be used.

Gamepad#

AdjustDistanceViaControllerStick(...)

Adjusts Distance according to the captured controller stick position for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The axis sets which stick movement direction will be used (defaults to Y, e.g. up/down).

The maxAdjustmentPerSec value is the amount to add to Distance when the stick is fully displaced along the given axis. If null, DefaultDistanceSensitivityControllerStick will be used.

If useLeftStick is true, the left controller stick will be measured; otherwise the right stick will be measured. Defaults to false.

If invertStickControl is true, the calculated adjustment will be reversed.

AdjustDistanceViaControllerTriggers(...)

Adjusts Distance according to the captured controller trigger positions for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The maxAdjustmentPerSec value is the amount to add to Distance when the trigger is fully displaced. If null, DefaultDistanceSensitivityControllerTrigger will be used.

If leftTriggerIncreasesDistance is true, the left trigger will increase distance from the target and the right trigger decrease it; otherwise these directions will be reversed. Defaults to true.

AdjustDistanceViaButtonPress(...)

Adjusts Distance according to whether a certain button is depressed for this frame.

The deltaTime value is expected to be the time in seconds of this frame iteration.

The buttonToTestFor is the button that, when pressed, will adjust this property.

If reverse is true, the calculated adjustment will be reversed. Defaults to false. This parameter lets you specify two buttons in a pair that mirror each other by invoking this method twice (once with reverse as false and once with reverse as true).

The adjustmentPerSec value is the amount to add to Distance for each second this button is depressed. If null, DefaultDistanceSensitivityKeyOrButtonPress will be used.

Other#

AdjustDistance(...)

Adjusts Distance according to the given rate (adjustmentPerSec) and time step (deltaTime).

This method does not inspect any user input data but is provided as a convenience for building custom per-frame control code.

Default Controls#

The following snippets show the implementation of AdjustAllViaDefaultControls(...) for keyboard/mouse and gamepad respectively:

// AdjustAllViaDefaultControls(input.KeyboardAndMouse, deltaTime):

AdjustPitchViaMouseCursor(input, pitchAdjustmentPerPixel, invertMouseControl: invertPitchControl);
AdjustYawViaMouseCursor(input, yawAdjustmentPerPixel, invertMouseControl: invertYawControl);
AdjustDistanceViaMouseWheel(input, distanceAdjustmentPerWheelIncrement, invertMouseControl: invertDistanceControl);
// AdjustAllViaDefaultControls(input.GameControllersCombined, deltaTime):

AdjustPitchViaControllerStick(input, deltaTime, maxPitchAdjustmentPerSec, invertStickControl: invertPitchControl);
AdjustYawViaControllerStick(input, deltaTime, maxYawAdjustmentPerSec, invertStickControl: invertYawControl);
AdjustDistanceViaControllerTriggers(input, deltaTime, maxDistanceAdjustmentPerSec, leftTriggerIncreasesDistance: !invertDistanceControl);

Smoothing#

Smoothing changes how quickly the controller adjusts the camera to match the current target properties.

The Yaw, Pitch, and Distance target properties can have smoothing applied. Note that Yaw and Pitch share a single RotationSmoothingStrength setting — they cannot be smoothed independently of one another.

// Set properties' smoothing individually:
controller.RotationSmoothingStrength = Strength.VeryMild; // Applies to both Yaw and Pitch
controller.DistanceSmoothingStrength = Strength.VeryMild;

// Set all properties' smoothing simutaneously:
controller.SetGlobalSmoothing(Strength.VeryMild);

The default smoothing for all properties is VeryMild. You can choose from VeryMild, Mild, Moderate, Strong, VeryStrong, or None.

  • Smoothing makes the camera feel more 'real' or physical.
  • Higher strengths increase this feeling but also increase the latency between setting a target value and the camera actually meeting that target.
  • Setting the smoothing to None disables smoothing entirely. This means the camera will always be updated to meet exactly the target value of each property on each frame; reducing latency to 0 but making the camera feel less physical.
Custom Smoothing Values

If the enum-based approach is not specific enough for your needs, every property can instead have a custom smoothing strength applied via a method named like "SetCustom[...]SmoothingStrength".

This method takes a single float parameter that indicates the half-life of decay between the current value of a property and its target value.

For example, if the current value of X is 50 and the target value of X is 100, a half-life of 1f would move X to 75 after one second, and then 87.5 after the next second, and so-on.

Advanced: Smoothing is implemented via critically-damped spring. The smoothingHalfLife parameter is translated to become the Ω of the spring equation via the formula Ω = 1.6783469f / smoothingHalfLife.

Comments