Orbital Camera Controller
Summary#
The OrbitalCameraController orbits a camera around a Target location, always pointing at it. The camera's position relative to the target is set via the Angle, Height, and Distance properties. This is useful for "satellite" or "track-cam" style cameras that revolve around a fixed point.
- Adjusting
Anglerotates the camera around the target; - Adjusting
Heightraises or lowers the camera along theUpDirectionaxis; - Adjusting
Distancemoves the camera toward or away from the target on the orbital plane.
Example Usage#
// One time setup:
var controller = camera.CreateController<OrbitalCameraController>(); // (1)!
controller.Target = Location.Origin; // (2)!
controller.UpDirection = Direction.Up; // (3)!
controller.ZeroAngleDirection = Direction.Forward; // (4)!
// Per-frame:
controller.AdjustAllViaDefaultControls(input.KeyboardAndMouse, deltaTime); // (5)!
controller.AdjustAllViaDefaultControls(input.GameControllersCombined, deltaTime); // (6)!
controller.Progress(deltaTime); // (7)!
- This creates the controller, attached to the given
camera. - This sets the location the camera will orbit around (and always look at).
- This sets which way is "up" — the axis the camera orbits around when adjusting
Angle, and the direction the camera moves along when adjustingHeight. -
This sets the direction from
Targetto the camera whenAngleis zero. In other words, it controls where the camera starts on its orbit. -
This manipulates the camera according to the default keyboard and mouse scheme. The angle/height/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 angle/height/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#
-
Angle -
Sets how far around the orbit the camera has rotated, around the
UpDirectionaxis, starting fromZeroAngleDirection.Increasing this value rotates the camera anticlockwise around
UpDirection; decreasing rotates it clockwise.Defaults to
0°. -
Height -
Sets how far above (or below) the
Targetthe camera is, along theUpDirectionaxis.Defaults to
0.1f. -
Distance -
Sets how far from the
Targetthe camera is on the orbital plane (the plane perpendicular toUpDirection).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. -
UpDirection -
The axis the camera orbits around when adjusting
Angle, and the direction the camera moves along when adjustingHeight.Defaults to
Direction.Up. -
ZeroAngleDirection -
The direction from
Targetto the camera whenAngleis zero.This value is automatically orthogonalized against
UpDirection; if the result is invalid (e.g. parallel toUpDirection), an arbitrary orthogonal direction is chosen instead.Defaults to an arbitrary direction orthogonal to
UpDirection.
-
AngleRange -
Can be set to any value between
0°and360°to set the maximum amount the camera is permitted to rotate from itsZeroAngleDirection.This value is applied 50% in either direction equally (i.e. a value of
160°results in the camera being able to orbit 80° anticlockwise and 80° clockwise).Can be set to
nullto remove any limit (allowing full 360° orbits).Defaults to
null. -
MinHeight -
The minimum permitted value for
Height. Can benullto remove the lower bound.Defaults to
0.1f. -
MaxHeight -
The maximum permitted value for
Height. Can benullto remove the upper bound.Defaults to
0.5f. -
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.
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 Angle#
Keyboard / Mouse#
-
AdjustAngleViaMouseCursor(...) -
Adjusts
Angleaccording 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 toAnglefor each pixel moved according to the givenaxis. If null,DefaultAngleSensitivityMouseCursorwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustAngleViaMouseWheel(...) -
Adjusts
Angleaccording to the captured mouse wheel movement for this frame.The
adjustmentPerWheelIncrementvalue is the angle to add toAnglefor each scroll increment on the mouse wheel. If null,DefaultAngleSensitivityMouseWheelwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustAngleViaKeyPress(...) -
Adjusts
Angleaccording 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. Defaults tofalse. This parameter 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 toAnglefor each second this key is depressed. If null,DefaultAngleSensitivityKeyOrButtonPresswill be used.
Gamepad#
-
AdjustAngleViaControllerStick(...) -
Adjusts
Angleaccording 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 toAnglewhen the stick is fully displaced along the givenaxis. If null,DefaultAngleSensitivityControllerStickwill 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. -
AdjustAngleViaControllerTriggers(...) -
Adjusts
Angleaccording 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 toAnglewhen the trigger is fully displaced. If null,DefaultAngleSensitivityControllerTriggerwill be used.If
leftTriggerRotatesClockwiseis true, the left trigger will rotate clockwise and the right trigger anticlockwise; otherwise these directions will be reversed. Defaults totrue. -
AdjustAngleViaButtonPress(...) -
Adjusts
Angleaccording 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. Defaults tofalse. This parameter 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 toAnglefor each second this button is depressed. If null,DefaultAngleSensitivityKeyOrButtonPresswill be used.
Other#
-
AdjustAngle(...) -
Adjusts
Angleaccording 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 Height#
Keyboard / Mouse#
-
AdjustHeightViaMouseCursor(...) -
Adjusts
Heightaccording 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 toHeightfor each pixel moved according to the givenaxis. If null,DefaultHeightSensitivityMouseCursorwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustHeightViaMouseWheel(...) -
Adjusts
Heightaccording to the captured mouse wheel movement for this frame.The
adjustmentPerWheelIncrementvalue is the amount to add toHeightfor each scroll increment on the mouse wheel. If null,DefaultHeightSensitivityMouseWheelwill be used.If
invertMouseControlistrue, the calculated adjustment will be reversed. -
AdjustHeightViaKeyPress(...) -
Adjusts
Heightaccording 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. Defaults tofalse. This parameter 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 toHeightfor each second this key is depressed. If null,DefaultHeightSensitivityKeyOrButtonPresswill be used.
Gamepad#
-
AdjustHeightViaControllerStick(...) -
Adjusts
Heightaccording 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 toHeightwhen the stick is fully displaced along the givenaxis. If null,DefaultHeightSensitivityControllerStickwill 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. -
AdjustHeightViaControllerTriggers(...) -
Adjusts
Heightaccording 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 toHeightwhen the trigger is fully displaced. If null,DefaultHeightSensitivityControllerTriggerwill be used.If
leftTriggerRaisesHeightis true, the left trigger will raise the camera and the right trigger lower it; otherwise these directions will be reversed. Defaults totrue. -
AdjustHeightViaButtonPress(...) -
Adjusts
Heightaccording 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. Defaults tofalse. This parameter 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 toHeightfor each second this button is depressed. If null,DefaultHeightSensitivityKeyOrButtonPresswill be used.
Other#
-
AdjustHeight(...) -
Adjusts
Heightaccording 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#
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. Defaults tofalse. This parameter 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.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. Defaults tofalse. This parameter 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.
Default Controls#
The following snippets show the implementation of AdjustAllViaDefaultControls(...) for keyboard/mouse and gamepad respectively:
// AdjustAllViaDefaultControls(input.KeyboardAndMouse, deltaTime):
AdjustAngleViaMouseCursor(input, angleAdjustmentPerPixel, invertMouseControl: invertAngleControl);
AdjustHeightViaMouseCursor(input, heightAdjustmentPerPixel, invertMouseControl: invertHeightControl);
AdjustDistanceViaMouseWheel(input, distanceAdjustmentPerWheelIncrement, invertMouseControl: invertDistanceControl);
// AdjustAllViaDefaultControls(input.GameControllersCombined, deltaTime):
AdjustAngleViaControllerStick(input, deltaTime, maxAngleAdjustmentPerSec, invertStickControl: invertAngleControl);
AdjustHeightViaControllerStick(input, deltaTime, maxHeightAdjustmentPerSec, invertStickControl: invertHeightControl);
AdjustDistanceViaControllerTriggers(input, deltaTime, maxDistanceAdjustmentPerSec, leftTriggerIncreasesDistance: !invertDistanceControl);
Smoothing#
Smoothing changes how quickly the controller adjusts the camera to match the current target properties.
The Angle, Height, and Distance target properties can have smoothing applied.
// Set properties' smoothing individually:
controller.AngleSmoothingStrength = Strength.VeryMild;
controller.HeightSmoothingStrength = Strength.VeryMild;
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
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 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.