Depending on the settings in our project, data may not always arrive at a smooth 60 frames per second through the network. This is completely okay, but in order to make state changes (e.g. movement, rotation) appear smooth on the client, we use interpolation.
Interpolation is a type of estimation, a method of constructing new data points within the range of a discrete set of known data points.
The way interpolation works in coherence is that we wait for three data points and then start smoothing the subsequent values according to the interpolation parameters defined in the schema (or default parameters, if no overrides are present).
To override interpolation settings, create a new schema asset via Assets/Create/coherence/Schema
. Once created, mark it as an active schema in the settings window.
In this new schema, add an interpolation definition:
This interpolation definition MyInterpolation
isn't used yet. We need to tell coherence which component is going to use it. We can associate it to WorldPosition and WorldOrientation:
Although not necessary, we're also defining scale and bit depth in the example above.
There are a few fields you can tune to get the most out of interpolation:
overshootPercentage
How far into dead reckoning we can venture when the time fraction exceeds 100%
overshootRetraction
How fast to pull back to 100% if we overshoot the allowed dead reckoning maximum in seconds
manualLatency
Seconds to stay behind the sample data
autoLatencyFactor
targetInterpolation = autoLatencyFactor * packetDeltaTime
. -1
disables auto latency
elasticity
Seconds to remain behind the current interpolation point, applied to smoothdamp
function or slerp
maxDistance
maximum distance between data points before the component "teleports" to the next value without smoothing.
allowed values: positive real numbers
curveType
the type of interpolation used
allowed values: "CatmullRom"
, "Linear"
Interpolation can be overridden globally, per component and per LOD level. Here is a sample schema that defines a named interpolation style OverrideTranslation
and uses it for all WorldPosition
components.
Here's another example that overrides interpolation for WorldPosition
and WorldOrientation
:
Remember that everytime you change a schema, you need to Bake for the changes to make effect.
We need one last piece to tie everything together. We need a way to let our bindings to use this interpolation override. To do so, we can create a custom binding provider that extends how the transform component is bound. Create a file named CustomTransformBindingProvider.cs
in an Editor folder (e.g. Assets/Editor
), with these contents:
This will use OverrideTranslation
interpolation component for WorldPosition
, and OverrideRotation
for WorldOrientation
. You can use any name for these as long as it matches the names you defined in your schema. If you don't want to override one of these, just comment out the assignment you don't need.
After you compile this script, a popup will appear letting you know that your CoherenceSync assets have been updated to point to these new components you defined.
From here on, any additional change to interpolation you want to make, you can adjust the values in the schema and bake again.