Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move_and_slide uses instaneous velocity on rotating platforms resulting in drift #46604

Open
Tracked by #45333
e344fde6bf opened this issue Mar 2, 2021 · 1 comment

Comments

@e344fde6bf
Copy link
Contributor

e344fde6bf commented Mar 2, 2021

Godot version:

3.2.3.stable

OS/device including version:
N/A

Issue description:

When move_and_slide() is used on a rotating platform, it uses the instantaneous velocity at the point of collision. However, it should use the average velocity it would receive over the given time step:

velocity due to rotation

Here's a concrete example, that demonstrates the difference in behaviour:

Instantaneous velocity calculation:

sliding off the platform

Average velocity over delta time step:

fixed velocity calculation

This issue has been raised in the past (#35365, #16450). There it was state this was a correct physical simulation, however kinematic bodies don't under go proper physical simulations and the workarounds provided don't resolve this issue.

Note to get correct calculations in more complex scenarios, it is also necessary to resolve godotengine/godot-proposals#2332 and #46603. This is because the centre of rotation can move between frames, and it is necessary to calculate the exact position the two objects have relative to each for velocity calculations to be correct.

Steps to reproduce:

Create a KinematicBody that is controlled by move_and_slide() and stand on a rotating platform. Notice that over time the player gets thrown off the side of the platform.

Minimal reproduction project:

This project uses the correct velocity calculation. Press Q to toggle this behaviour on and off.

rotating-platform-fix.zip

@e344fde6bf e344fde6bf changed the title move_and_slide uses instaneous velocity on rotating platforms resulting in drift move_and_slide uses instaneous velocity on rotating platforms resulting in drift Mar 2, 2021
@TheBoctor
Copy link

Has anyone had luck working around this in Godot 4? I'm facing the same drift issues with spinning floors as of 4.3, and it looks like an engine-level solution (incl. the two blockers linked here) might be the only "correct" one at this point. Sadly, GDExtension does not currently expose platform_object_id or the platform data struct in CharacterBody3D, so my initial idea of hotfixing it via addon is impossible.

This workaround still mostly works, but there is no straightforward, guaranteed way to get the collider of a moving floor from a CharacterBody3D in GDScript. There are also moments when a moving platform is briefly not detected during a move/slide, or is not the 0th collision. Due to significant changes between 3.x and 4.x, the velocity from a platform can also accumulate during move_and_slide() in unintended ways. Even with all of that worked around via abuse of calling move_and_slide twice with different floor masks and velocities, my attempt at a new workaround was too brittle to be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants