Camera Dampers
Last updated
Last updated
V0.2.2 refactored the damping representation in this plugin. Before V0.2.2, all damping methods and their implementations are encapsulated in a single struct. V0.2.2 abstracts the damper representation so that each damper is relatively independent. This provides more flexibility and extensibility.
Some components have already contained pre-defined dampers. For example, the ScreenFollow component contains an aggregate damper comprising three sub-dampers. Each sub-damper is responsible for damping a particular axis of current camera's positional movement.
You can choose any of the pre-defined sub-damper to meet your needs. The default sub-damper is NaiveDamper. This is also the damper you're supposed to use for most of the time. It's simple and effecient, and generally lead to nice damping effects.
There are six pre-defined dampers as shown below. The Continuous Naive Damper,
Lowpass Naive Damper
, Restrict Naive Damper
and Simulate Damper
are used to solve the camera jittering problem when the game's frames per second (FPS) is unstable. For most cases you should use the Naive Damper
and for specific gameplay, you can use the Spring Damper
.
Naive Damper: Uses a simple residual-based damping algorithm. This is the damper you should choose for most of the time.
Damp Time: amount of time to finish damping.
Residual: damp residual after damp time (in percent).
Simulate Damper: Splits the given deltaTime into multiple segments and simulates naive damping in order.
Damp Time: amount of time to finish damping.
Residual: damp residual after damp time (in percent).
Simulate Count: Number of simulations per damping.
Continuous Naive Damper: Continuous optimization when FPS is unstable. Reference.
Damp Time: amount of time to finish damping.
Residual: damp residual after damp time (in percent).
Order: Orders of derivative you want to use for approximation. Larger means more accurate.
Restrict Naive Damper: Restrict damp velocity when FPS in unstable. Reference.
Damp Time: amount of time to finish damping.
Residual: damp residual after damp time (in percent).
Tolerance: Tolerance of restriction range.
Power: Controls how aggresively to compact the curve.
Lowpass Naive Damper: Low-pass filtering optimization when FPS in unstable. Reference.
Damp Time: amount of time to finish damping.
Residual: damp residual after damp time (in percent).
Tolerance: Tolerance of restriction range.
Beta: Smaller means smoother.
Spring Damper: Uses spring to damp. Reference.
Frequency: Controls the frequency of oscillation and the speed of decay.
Damp Ratio: Controls whether the spring is undamped (=0), underdamped (<1), critically damped (=1), or overdamped (>1).
A damper typically receives a single input value, damps it and returns the output damped value. There're six built-in dampers and you can customize your own damper.
Create a new blueprint class inheriting ECameraDamper
.
Implement the ApplyDamp
function and the PostApplyDamp
function.
In the following figure, I create my custom damper MyDamper
, and create two variables DampTime
and OtherParameters
. The ApplyDamp
implements a simple linear damping algorithm and the PostApplyDamp
is used to update any internal parameter.
Select MyDamper
at wherever you would like to use your damper.
Play and see if it works correctly.
An aggregate damper is a damper consisting of multiple sub-dampers, like the ECamera Vector Damper
in ScreenFollow. It's highly related to the function and purpose of the component it resides in. For example, an ECamera Vector Damper
aggregate damper is used for any Vector-like data, and an ECamera Rotator Damper
, as in TargetingAim, is used for any Rotation-like data. That's to say, if you have a Vector2d data, you may prefer a ECamera Pair Damper
aggregate damper.
To create your own MyPairDamper
aggregate damper, create a new blueprint class inheriting ECamera Aggregate Damper
, and create two variables of type ECamera Damper
, designate their default damper types and parameters. That's it.
It should be emphasized again that your new aggregate damper can only be used in conjunction with your own customized components. There is no place in the built-in components where you can use your aggregate damper.
For example, in the following customized follow component MyFollowComponent
, I add a variable Damper
of type MyPairDamper
, the one we just created. Then in the Class Defaults Details panel, select My Pair Damper
.
When you use this component, the default value for Damper
will be My Pair Damper
.
So how do you update this custom damper inside your component? Two steps.
The first step is to define several update functions in your damper. In the example of MyPairDamper
, you can define four functions:
SetInput:Take a Vector2D data as input and feed the X/Y component to Damper X/Y. The input will be damped by a damper.
SetOutput: Take a Vector2D data as input and feed the X/Y component to Damper X/Y. This is an interface to allow external modifications on the output derived by a damper. The modified output is then propagated into the damper internally.
ApplyDamp: Each damper applies damping.
PostApplyDamp: An interface allowing each damper to update its internal parameters. For example, the Spring Damper
has velocity as its internal mutable parameter and is updated each frame.
A typical workflow of an aggregate damper is to sequentially call SetInput->ApplyDamp->SetOutput (Optional)->PostApplyDamp.
In the following example of MyFollowComponent
, you can see how the Damper
processes the Position
variable.
You can also comprehen an aggregate damper as a template. For example, in some cases you may want all the three sub-dampers in ECamera Damper Vector
to be Spring Damper
, and in other cases, you want the Damper X
to be Spring Damper
and Damper Y/Z
to be Naive Damper
. To this end, you can inherit ECamera Damper Vector
and specify the concrete type for each sub-damper. Then, in the component, say ScreenFollow, you can directly use your customized version of ECamera Damper Vector
without specifying the type of each sub-damper.
As an example, I create my own aggregate damper named MyDamperVector
inheriting from ECamera Damper Vector
and have all sub-dampers be Spring Damper
.
In the ScreenFollow component, all I need to do is choose My Damper Vector
. This will save much time tuning the types and parameters of sub-dampers for each component of each camera by customizing some commonly-used damper templates.