A general-purpose Transform
interpolation plugin for fixed timesteps in Avian Physics for the Bevy engine.
examples/split_screen_comparison.rs
:
comparison.mp4
Note: The interpolation on the left is smoother in reality, blame the video recording software ;)
Ever had your character jitter around when making the camera follow them? This plugin may be for you!
For a full explanation, see Bevy's physics_in_fixed_timestep
example.
The short version is that on fast enough machines, your game will update its
rendered frame more often than it will update its physics simulation.
This means that sometimes e.g. your camera will be moved around without any physics
objects being updated this frame. This will lead to the physics object's movement
looking chppy and jittery, like on the right window in the video above.
There are a number of ways in which we can deal with this, and the easiest is interpolation. By letting the visuals of the physics objects intentionally lag a tiiiiiny bit behind, we can smoothly interpolate between the last two values, leading to smooth and correct visuals, at the cost of the rendered objects being behind the underlying physics objects by a bit. How much? Well, long story short, expect the physics to be ahead of the graphics by a single digit millisecond value. For most games, that is not noticeable at all and will just "magically" make the game more smooth, like on the left window in the video above :)
Add the plugin to your project. Replace 3d
with 2d
if you are using Avian 2D.
cargo add avian_interpolation3d --git https://github.com/janhohenheim/avian_interpolation
it's not on crates.io yet because I'm waiting for a new Avian
release, as this was made
targeting the main
branch. This means you also need to use the main
branch of Avian
.
Again, replace 3d
with 2d
if you are using Avian 2D.
cargo add avian3d --git https://github.com/Jondolf/avian
Now, add AvianInterpolationPlugin
to your app after PhysicsPlugins
and everything Just Works™:
App::new()
.add_plugins((
DefaultPlugins,
// Disabling SyncPlugin is optional, but will get you a performance boost.
PhysicsPlugins::default().build().disable::<SyncPlugin>(),
AvianInterpolationPlugin::default(),
))
.run();
And that's it! The Transform
component of all moving objects will now be interpolated after the physics simulation.
This means that the new Transform
will be available in Update
for rendering, spatial sound, moving your camera, etc.
The interpolation source will be their Position
and Rotation
.
- Disables transform syncing, i.e. Avian's feature of translating
Transform
to its internal representation and vice versa.- In practice, this means that you can not directly modify the
Transform
component of any rigid body anymore. UsePosition
andRotation
instead.Transform
is a purely aesthetic component and should not be modified for physics. Depending on your point of view, this is actually a feature ;) - You can still read the
Transform
of anything just as you would always do, if you want. - If you still want to have your
Transform
changed as if you had transform syncing enabled, setInterpolateTransformFields::translation
orInterpolateTransformFields::rotation
toInterpolationMode::Last
for that entity. This will use the last available physics transform as the interpolation source instead.
- In practice, this means that you can not directly modify the
- Assumes
PhysicsSchedule
is left at its default value ofFixedPostUpdate
. - Assumes that all entities with
Position
will also haveRotation
and vice versa. - Assumes
RigidBody
s will not form hierarchies with otherRigidBody
s. - Assumes
Rigidbody::Static
objects will not move. - Will not interpolate scales for you
bevy_transform_interpolation
works withTransform
in general, while this plugin works only for Avian.- This plugin makes the results of the interpolation available for systems in
Update
, which is nicer to work with thanbevy_transform_interpolation
'sPostUpdate
. - By the above features and limitations, this plugin is less memory-intensive and does fewer checks per entity. I didn't do any benchmarks, but it should be faster. Blazingly fast, some may say.
- For most use-cases, this should work as a drop-in replacement for
bevy_transform_interpolation
as long as you don't mutate rigid bodies'Transform
s by hand.
avian_interpolation |
avian |
bevy |
---|---|---|
main |
main |
0.14 |