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
Yawrotates the camera around the target; - Adjusting
Pitchtilts the camera up or down relative to the target; - Adjusting
Distancemoves the camera toward or away from the target.
For an overview of how camera controllers work in general, see Camera Controllers.
Example Usage#
// One time setup:
var controller = camera.CreateController<InspectorCameraController>(); // (1)!
controller.WorldUp = Direction.Up; // (2)!
controller.SetConstraints(myMesh.BoundingBox); // (3)!
// Per-frame:
controller.AdjustAllViaDefaultControls(input.KeyboardAndMouse, deltaTime); // (4)!
controller.AdjustAllViaDefaultControls(input.GameControllersCombined, deltaTime); // (5)!
controller.Progress(deltaTime); // (6)!
- This creates the controller, attached to the given
camera. -
This sets which way is "up" — the axis the camera yaws around, and the reference for what "up" means when tilting via
Pitch. -
This sets the camera's
Target,MinDistance,MaxDistanceandDistanceproperties according to the bounding box of the mesh you want to inspect (seeSetConstraints()below).For multiple models/meshes (e.g. as loaded by
LoadAll()) you can calculate an amalgamated bounding box via e.g.loadedAssetData.Models.CalculateCombinedBoundingBox().Using this method is optional; you can set those properties manually if preferred.
-
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.
-
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.
-
Calling
Progress()once per frame is required on all camera controllers in order for them to actually alter their targetCamera's parameters.
Properties#
Per-Frame Targets#
-
Yaw -
Sets how far around the target the camera has rotated, around the
WorldUpaxis.Increasing this value turns the camera anticlockwise around the target (when
WorldUpis pointing towards you); decreasing turns clockwise.The value read back is always normalized to between
0°and360°(e.g. setting-30°reads back as330°).Defaults to
0°. -
Pitch -
Sets how high or low the camera is tilted relative to the target.
A value of
0°places the camera level with the target on the horizontal plane; positive values raise the camera above the target (looking down at it), negative values lower it below the target (looking up at it).By default, this value is automatically clamped to ±90° during
Progress()so that the camera never flips upside-down. SetAllowUpsideDownFliptotrueto disable this behavior.Like
Yaw, the value read back is normalized to between0°and360°(so a pitch of-30°reads back as330°, and-90°as270°).Defaults to
0°. -
Distance -
Sets how far from the
Targetthe camera is.This value will be clamped between
MinDistanceandMaxDistancewhen either are non-null. Negative or non-finite values are ignored.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
Pitchis interpreted relative to it.Defaults to
Direction.Up. -
AllowUpsideDownFlip -
When
false(the default),Pitchis 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 benullto remove the lower bound.Defaults to
0.6f. -
MaxDistance -
The maximum permitted value for
Distance. Can benullto remove the upper bound.Defaults to
2f.
Both distance limits must be positive (invalid values are ignored). Setting MinDistance higher than MaxDistance raises MaxDistance to match (and vice versa), and Distance is re-clamped immediately.
-
SetConstraints(boundingBox)/SetConstraints(boundingBox, worldUp) -
A convenience method for inspecting a single object or set of models: sets
Target,MinDistance,MaxDistance, andDistancetogether from the suppliedboundingBox(aPositionedCuboid). The second overload also setsWorldUp.Specifically, the smallest sphere enclosing the cuboid is calculated; then:
Targetis set to the centre of that sphere.MinDistanceis set to the smaller of the sphere's radius and the cuboid's smallest half-extent, letting the camera come in close to thin objects. If the cuboid is completely flat (its smallest half-extent is0), the sphere's radius is used instead.MaxDistanceis set to three times the sphere's radius.Distanceis set to one-and-a-half times the sphere's radius (a sensible default starting offset).
If the cuboid has no size at all, only
Target(andWorldUp) are changed. -
SetConstraints(target, worldUp, allowUpsideDownFlip, minDistance, maxDistance) -
Sets
Target,WorldUp,AllowUpsideDownFlip,MinDistance, andMaxDistancein one call. (Unlike the bounding box overloads, this does not setDistance, thoughDistanceis still re-clamped to the new limits.) -
Progress(deltaTime, yaw, pitch, distance) -
Sets
Yaw,Pitch, andDistance, then callsProgress(deltaTime). -
ResetParametersToDefault() -
Resets every property (including smoothing) to its default value.
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
Pitchaccording to the captured mouse cursor movement for this frame.The
axissets which cursor movement direction will be used (defaults toY, e.g. up/down).The
adjustmentPerPixelvalue is the angle to add toPitchfor each pixel moved according to the givenaxis. If null,DefaultPitchSensitivityMouseCursorwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustPitchViaMouseWheel(...) -
Adjusts
Pitchaccording to the captured mouse wheel movement for this frame.The
adjustmentPerWheelIncrementvalue is the angle to add toPitchfor each scroll increment on the mouse wheel. If null,DefaultPitchSensitivityMouseWheelwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustPitchViaKeyPress(...) -
Adjusts
Pitchaccording to whether a certain key is depressed for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
keyToTestForis the key that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two keys in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the angle to add toPitchfor each second this key is depressed. If null,DefaultPitchSensitivityKeyOrButtonPresswill be used.
Gamepad#
-
AdjustPitchViaControllerStick(...) -
Adjusts
Pitchaccording to the captured controller stick position for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
axissets which stick movement direction will be used (defaults toY, e.g. up/down).The
maxAdjustmentPerSecvalue is the angle to add toPitchwhen the stick is fully displaced along the givenaxis. If null,DefaultPitchSensitivityControllerStickwill be used.If
useLeftStickis true, the left controller stick will be measured; otherwise the right stick will be measured. Defaults tofalse.If
invertStickControlistrue, the calculated adjustment will be reversed. -
AdjustPitchViaControllerTriggers(...) -
Adjusts
Pitchaccording to the captured controller trigger positions for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
maxAdjustmentPerSecvalue is the angle to add toPitchwhen the trigger is fully displaced. If null,DefaultPitchSensitivityControllerTriggerwill be used.If
leftTriggerPitchesUpis true, the left trigger will increasePitch(raising the camera up over the target) and the right trigger decrease it; otherwise these directions will be reversed. Defaults totrue. -
AdjustPitchViaButtonPress(...) -
Adjusts
Pitchaccording to whether a certain button is depressed for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
buttonToTestForis the button that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two buttons in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the angle to add toPitchfor each second this button is depressed. If null,DefaultPitchSensitivityKeyOrButtonPresswill be used.
Other#
-
AdjustPitch(...) -
Adjusts
Pitchaccording 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
Yawaccording to the captured mouse cursor movement for this frame.The
axissets which cursor movement direction will be used (defaults toX, e.g. left/right).The
adjustmentPerPixelvalue is the angle to add toYawfor each pixel moved according to the givenaxis. If null,DefaultYawSensitivityMouseCursorwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustYawViaMouseWheel(...) -
Adjusts
Yawaccording to the captured mouse wheel movement for this frame.The
adjustmentPerWheelIncrementvalue is the angle to add toYawfor each scroll increment on the mouse wheel. If null,DefaultYawSensitivityMouseWheelwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustYawViaKeyPress(...) -
Adjusts
Yawaccording to whether a certain key is depressed for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
keyToTestForis the key that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two keys in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the angle to add toYawfor each second this key is depressed. If null,DefaultYawSensitivityKeyOrButtonPresswill be used.
Gamepad#
-
AdjustYawViaControllerStick(...) -
Adjusts
Yawaccording to the captured controller stick position for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
axissets which stick movement direction will be used (defaults toX, e.g. left/right).The
maxAdjustmentPerSecvalue is the angle to add toYawwhen the stick is fully displaced along the givenaxis. If null,DefaultYawSensitivityControllerStickwill be used.If
useLeftStickis true, the left controller stick will be measured; otherwise the right stick will be measured. Defaults tofalse.If
invertStickControlistrue, the calculated adjustment will be reversed. -
AdjustYawViaControllerTriggers(...) -
Adjusts
Yawaccording to the captured controller trigger positions for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
maxAdjustmentPerSecvalue is the angle to add toYawwhen the trigger is fully displaced. If null,DefaultYawSensitivityControllerTriggerwill be used.If
leftTriggerYawsClockwiseis true, the left trigger will yaw clockwise and the right trigger yaw anticlockwise; otherwise these directions will be reversed. Defaults totrue. -
AdjustYawViaButtonPress(...) -
Adjusts
Yawaccording to whether a certain button is depressed for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
buttonToTestForis the button that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two buttons in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the angle to add toYawfor each second this button is depressed. If null,DefaultYawSensitivityKeyOrButtonPresswill be used.
Other#
-
AdjustYaw(...) -
Adjusts
Yawaccording 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
Distanceaccording to the captured mouse cursor movement for this frame.The
axissets which cursor movement direction will be used (defaults toY, e.g. up/down).The
adjustmentPerPixelvalue is the amount to add toDistancefor each pixel moved according to the givenaxis. If null,DefaultDistanceSensitivityMouseCursorwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustDistanceViaMouseWheel(...) -
Adjusts
Distanceaccording to the captured mouse wheel movement for this frame.The
adjustmentPerWheelIncrementvalue is the amount to add toDistancefor each scroll increment on the mouse wheel. If null,DefaultDistanceSensitivityMouseWheelwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustDistanceViaKeyPress(...) -
Adjusts
Distanceaccording to whether a certain key is depressed for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
keyToTestForis the key that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two keys in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the amount to add toDistancefor each second this key is depressed. If null,DefaultDistanceSensitivityKeyOrButtonPresswill be used.
Gamepad#
-
AdjustDistanceViaControllerStick(...) -
Adjusts
Distanceaccording to the captured controller stick position for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
axissets which stick movement direction will be used (defaults toY, e.g. up/down).The
maxAdjustmentPerSecvalue is the amount to add toDistancewhen the stick is fully displaced along the givenaxis. If null,DefaultDistanceSensitivityControllerStickwill be used.If
useLeftStickis true, the left controller stick will be measured; otherwise the right stick will be measured. Defaults tofalse.By default, pushing the stick upward moves the camera closer to the target. If
invertStickControlistrue, the calculated adjustment will be reversed. -
AdjustDistanceViaControllerTriggers(...) -
Adjusts
Distanceaccording to the captured controller trigger positions for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
maxAdjustmentPerSecvalue is the amount to add toDistancewhen the trigger is fully displaced. If null,DefaultDistanceSensitivityControllerTriggerwill be used.If
leftTriggerIncreasesDistanceis true, the left trigger will increase distance from the target and the right trigger decrease it; otherwise these directions will be reversed. Defaults totrue. -
AdjustDistanceViaButtonPress(...) -
Adjusts
Distanceaccording to whether a certain button is depressed for this frame.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
buttonToTestForis the button that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two buttons in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the amount to add toDistancefor each second this button is depressed. If null,DefaultDistanceSensitivityKeyOrButtonPresswill be used.
Other#
-
AdjustDistance(...) -
Adjusts
Distanceaccording 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.
Adjusting Distance (Percentage)#
These methods are direct counterparts to the AdjustDistance... family above, but each adjustment is interpreted as a fraction of the current MaxDistance - MinDistance range rather than as an absolute world-units delta.
This is generally preferable when inspecting an object whose size is not known up-front (e.g. after calling SetConstraints(...)) — the controls feel consistent regardless of how large or small the framed object is.
If either MinDistance or MaxDistance is null, the methods fall back to adding the adjustment directly (i.e. they degenerate to using the same units as the equivalent AdjustDistance... methods).
Keyboard / Mouse#
-
AdjustDistancePercentageViaMouseCursor(...) -
Adjusts
Distanceaccording to the captured mouse cursor movement for this frame, scaled by the current distance range.The
axissets which cursor movement direction will be used (defaults toY, e.g. up/down).The
adjustmentPerPixelvalue is the fraction of the distance range (where1fis the whole range) to add for each pixel moved according to the givenaxis. If null,DefaultDistancePercentageSensitivityMouseCursorwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustDistancePercentageViaMouseWheel(...) -
Adjusts
Distanceaccording to the captured mouse wheel movement for this frame, scaled by the current distance range.The
adjustmentPerWheelIncrementvalue is the fraction of the distance range to add for each scroll increment on the mouse wheel. If null,DefaultDistancePercentageSensitivityMouseWheelwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustDistancePercentageViaKeyPress(...) -
Adjusts
Distanceaccording to whether a certain key is depressed for this frame, scaled by the current distance range.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
keyToTestForis the key that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two keys in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the fraction of the distance range to add for each second this key is depressed. If null,DefaultDistancePercentageSensitivityKeyOrButtonPresswill be used.
Gamepad#
-
AdjustDistancePercentageViaControllerStick(...) -
Adjusts
Distanceaccording to the captured controller stick position for this frame, scaled by the current distance range.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
axissets which stick movement direction will be used (defaults toY, e.g. up/down).The
maxAdjustmentPerSecvalue is the fraction of the distance range to add when the stick is fully displaced along the givenaxis. If null,DefaultDistancePercentageSensitivityControllerStickwill be used.If
useLeftStickis true, the left controller stick will be measured; otherwise the right stick will be measured. Defaults tofalse.By default, pushing the stick upward moves the camera closer to the target. If
invertStickControlistrue, the calculated adjustment will be reversed. -
AdjustDistancePercentageViaControllerTriggers(...) -
Adjusts
Distanceaccording to the captured controller trigger positions for this frame, scaled by the current distance range.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
maxAdjustmentPerSecvalue is the fraction of the distance range to add when the trigger is fully displaced. If null,DefaultDistancePercentageSensitivityControllerTriggerwill be used.If
leftTriggerIncreasesDistanceis true, the left trigger will increase distance from the target and the right trigger decrease it; otherwise these directions will be reversed. Defaults totrue. -
AdjustDistancePercentageViaButtonPress(...) -
Adjusts
Distanceaccording to whether a certain button is depressed for this frame, scaled by the current distance range.The
deltaTimevalue is expected to be the time in seconds of this frame iteration.The
buttonToTestForis the button that, when pressed, will adjust this property.If
reverseistrue, the calculated adjustment will be reversed. This parameter is required, and lets you specify two buttons in a pair that mirror each other by invoking this method twice (once withreverseasfalseand once withreverseastrue).The
adjustmentPerSecvalue is the fraction of the distance range to add for each second this button is depressed. If null,DefaultDistancePercentageSensitivityKeyOrButtonPresswill be used.
Other#
-
AdjustDistancePercentage(...) -
Adjusts
Distanceaccording to the given rate (adjustmentPerSec) and time step (deltaTime), scaled by the current distance range.A second overload,
AdjustDistancePercentage(adjustment), applies a single one-off adjustment (as a fraction of the distance range) with no time step; e.g.AdjustDistancePercentage(-0.1f)moves the camera 10% of the range closer.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. Every parameter after deltaTime is optional: invertPitchControl, invertYawControl, and invertDistanceControl reverse each control, and the sensitivity parameters (pitchAdjustmentPerPixel, yawAdjustmentPerPixel, and distancePercentageAdjustmentPerWheelIncrement for keyboard/mouse; maxPitchAdjustmentPerSec, maxYawAdjustmentPerSec, and maxDistancePercentageAdjustmentPerSec for gamepad) fall back to the default sensitivity constants when null:
// AdjustAllViaDefaultControls(input.KeyboardAndMouse, deltaTime):
AdjustPitchViaMouseCursor(input, pitchAdjustmentPerPixel, invertMouseControl: invertPitchControl);
AdjustYawViaMouseCursor(input, yawAdjustmentPerPixel, invertMouseControl: invertYawControl);
AdjustDistancePercentageViaMouseWheel(input, distancePercentageAdjustmentPerWheelIncrement, invertMouseControl: invertDistanceControl);
// AdjustAllViaDefaultControls(input.GameControllersCombined, deltaTime):
AdjustPitchViaControllerStick(input, deltaTime, maxPitchAdjustmentPerSec, invertStickControl: invertPitchControl);
AdjustYawViaControllerStick(input, deltaTime, maxYawAdjustmentPerSec, invertStickControl: invertYawControl);
AdjustDistancePercentageViaControllerTriggers(input, deltaTime, maxDistancePercentageAdjustmentPerSec, 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 = SmoothingStrength.VeryMild; // Applies to both Yaw and Pitch
controller.DistanceSmoothingStrength = SmoothingStrength.VeryMild;
// Set all properties' smoothing simultaneously:
controller.SetGlobalSmoothing(SmoothingStrength.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
Nonedisables 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 SetCustomRotationSmoothingStrength() or SetCustomDistanceSmoothingStrength().
Each method takes a single float parameter that indicates the half-life of decay between the current value of a property and its target value. A half-life of 0f disables smoothing.
The half-life is the time (in seconds) the camera takes to cover half the distance to a new target value, starting from rest. 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. Because the smoothing carries momentum (see below), X would then be at roughly 92 after the next second, rather than 87.5.
Advanced: Smoothing is implemented via a critically-damped spring, which is why it carries momentum. The smoothingHalfLife parameter is translated to become the Ω of the spring equation via the formula Ω = 1.6783469f / smoothingHalfLife.