bevy_xpbd
bevy_xpbd copied to clipboard
Inconsistent Behavior with Velocity Calculations and Frame Rates in 2D Movement
Description:
I've encountered several strange behaviors while trying to implement top-down directional movement in my game using Bevy version 0.14.1 and Avian2D version 0.1.2. Here are the issues I faced:
-
Linear Velocity Acting Strangely:
I downloaded some 2D examples and ran both kinematic and dynamic examples. On my 240fps monitor, the game appeared to run slower compared to a 60fps monitor.-
Observation: When I removed
Time.deltaTimefrom the calculations, everything seemed to work correctly, which led me to assume that this adjustment would also apply to angular velocity. -
Problem: However, for angular velocity, removing
Time.deltaTimecaused erratic behavior on different screens. When I addedTime.deltaTimeback, it worked as expected.
-
-
Linear Velocity and Object Orientation:
Another issue is withlinear_velocity.xandlinear_velocity.ynot aligning with the object's orientation. I tried multiplyinglinear_velocity.xbytransform.up().normalized(), which worked to some extent.- Observation: I noticed that the aircraft slows down when turning, as if it's losing speed while turning. This behavior was unexpected.
This issue is a follow-up to issue #498, but I decided to create a new issue due to the weird behavior related to linear_velocity and Time.deltaTime.
Steps to Reproduce:
- Use a high refresh rate monitor (e.g., 240fps).
- Run the 2D kinematic and dynamic examples in Bevy with Avian2D.
- Observe the difference in game speed at different frame rates.
- Modify the velocity calculations by removing or adding
Time.deltaTime.
Expected Behavior:
- The game should run consistently across different frame rates.
linear_velocityshould respect the object's orientation without unexpected speed loss during turns.
Actual Behavior:
- Game speed varies with frame rate.
- Removing
Time.deltaTimecauses erratic angular velocity behavior. - The aircraft loses speed when turning.
Environment:
- Monitor refresh rate: 240fps, 60fps
- Bevy version: 0.14.1
- Avian2D version: 0.1.2
- Operating System: Ubuntu.22.0.4
Additional Context:
- This issue might be related to how
Time.deltaTimeis being applied or calculated within the physics update.
Thank you for looking into this issue!
I am seeing something similar when I run the dynamic_character_2d example. I found it quite easy to reproduce by turning VSync on and off like so:
DefaultPlugins.set(WindowPlugin {
primary_window: Some({
Window {
// present_mode: bevy::window::PresentMode::AutoVsync,
present_mode: bevy::window::PresentMode::AutoNoVsync,
..Default::default()
}
}),
..Default::default()
})
We can observe the issue with movement along the X axis, the Y axis is unaffected as it is not multiplied by the delta time.
I downloaded some 2D examples and ran both kinematic and dynamic examples. On my 240fps monitor, the game appeared to run slower compared to a 60fps monitor.
I think the issue here is that in the dynamic and kinematic examples the apply_movement_damping system applies the same damping every frame regardless of the time between frames. I fixed it by doing something like
linear_velocity.x *= 1.0 - damping_factor.0 * delta_time;
Though I'm not sure you can technically still call it a damping factor in this case.
linear_velocity.x *= 1.0 - damping_factor.0 * delta_time;
This is going to have bad behavior if delta_time gets large and the total factor goes negative. Looking at this https://theorangeduck.com/page/spring-roll-call. I think what you want is:
linear_velocity.x *= exp2(-delta_time * damping_factor.0)
edit: I guess you normally would use an approximation of the exponential, so this becomes:
linear_velocity.x *= 1 / (1 + damping_factor.0 * delta_time);