Make move_and_slide collision detection more accurate #50063
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR refines what was done in #49901 for
move_and_slide
and improves character collision detection in godot physics in general.Fixes #50062
Fixes #18433 (with both Bullet and Godot Physics)
Credits to @fabriceci for investigating move and slide issues and helping with finding the proper way to solve them, as well as extensive testing.
More accurate unsafe motion calculation
-Safe and unsafe motion are calculated by dichotomy with a limited number of steps. It's good for performance, but on long motions that either collide near the beginning or near the end, the result can be very imprecise.
-Now a factor 0.25 or 0.75 is used to converge faster when this case happens, which allows longer motions to get more accurate collision detection.
-Makes snap collision more precise, and helps with cases where diagonal collision on the border of a platform can lead to the character being stuck.
Additional improvements to move_and_slide
-Handle slide canceling in move_and_collide with 0 velocity instead of not applying it.
-Better handling of snap with custom logic to cancel sliding.
-Remove small jittering when using stop on slope, by canceling the motion completely when the resulting motion is less than margin instead of always projecting to the up direction (in both body motion and snap).
The same regression tests as for #49901 have been run to make sure things are still working well in other cases.
Move and slide test project made by @fabriceci:
https://github.com/fabriceci/move_and_slide
-Select
Classic C++
mode to test standardmove_and_slide
function-
Classic gdscript
is the gdscript conversion ofmove_and_slide
(now updated with this PR)-Other modes are specific tests for other changes being evaluated
Regression tests
2D Physics tests from Godot demos:
https://github.com/godotengine/godot-demo-projects/tree/master/2d/physics_tests
Functional Tests/Character - Slopes: no regression with KinematicBody2D moving on slopes.
Functional Tests/Character - Tilemap: no regression with KinematicBody2D jumping through one-way collision tiles.
Functional Tests/One Way Collision: no regression with one-way collision at different angles (current state: #42574 (review))
2D test with MRP from #45259:
No regression.
2D test with MRP from #46134:
No regression.
2D test with MRP from #21595:
No regression when moving on slopes. Slightly better stability on flat ground.
2D test with MRP from #31097:
No regression.
2D test with MRP from #45004:
No regression.
3D test with #35945 (comment):
No regression. The issue actually doesn't occur anymore with a safe margin of
0.01
, so the change from #40377 to make0.001
the default value is probably not needed anymore (to be investigated).3D test with MRP from #33833:
No regression.