-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Fix Rayshape not working properly in move_and_slide and move_and_slide_with_snap #45005
Conversation
I wonder if you should handle this on the move and snap, instead. If you apply the margin on the move and snap raycast call, and then you remove the margin just before apply the height on the character, you can fix it for any engine integrates the |
@AndreaCatania The snap code doesn't know about the ray at all, which is a shape of the kinematic body, handled in the server. In Bullet, it would have to be fixed in |
These changes improve Rayshape behavior for Godot Physics 2D and 3D when using move_and_slide with and without snapping. Kinematic margin is now applied to ray shapes when handling snapping collision tests and separation raycasts to help getting consistent results in slopes and flat surfaces. Recovery is calculated without the margin and a depth of 0 is still considered a collision to stabilize results when on flat surface. Recovery is split based on the amount of shapes to fix cases where multiple rayshapes would cause the body to bounce. Fixes godotengine#34098 Fixes godotengine#34663
3faee92
to
a3d8043
Compare
I've pushed extra changes in All these changes have to be done together, because the previous changes were causing things to be worse in some cases without snap (by taking kinematic margin into account for ray separation tests). |
if (depth > result.collision_depth) { | ||
result.collision_depth = depth; | ||
result.collision_point = b; | ||
result.collision_normal = (b - a).normalized(); | ||
result.collision_normal = ray_normal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always using raycast normal as a result, to make sure it only does separation, as described in this article:
https://godotengine.org/article/godot-31-will-get-many-improvements-kinematicbody
body_transform.elements[2] += recover_motion; | ||
body_aabb.position += recover_motion; | ||
|
||
recover_attempts--; | ||
} while (recover_attempts); | ||
} | ||
|
||
//optimize results (remove non colliding) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is not needed anymore, since we're considering hits at depth 0 as a collision now, in order to stabilize floor tests.
As a side note, this block was not working correctly, as it would skip one element after each swap.
Proper implementation would have been:
for (int i = 0; i < rays_found; i++) {
if (r_results[i].collision_depth == 0) {
rays_found--;
SWAP(r_results[i], r_results[rays_found]);
i--; // because we need to check the element we just moved
}
}
Needs a rebase. |
Closing since ray shapes have been removed on master. |
These changes improve Rayshape behavior for Godot Physics 2D and 3D when using move_and_slide with and without snapping.
Kinematic margin is now applied to ray shapes when handling snapping collision tests and separation raycasts to help getting consistent results in slopes and flat surfaces.
Recovery is calculated without the margin and a depth of 0 is still considered a collision to stabilize results when on flat surface.
Recovery is split based on the amount of shapes to fix cases where multiple rayshapes would cause the body to bounce.
Fixes #34098 (Godot Physics only, still happens in Bullet)
Fixes #34663 (Godot Physics only, still happens in Bullet)
Fixes #27689
3.2 version of this PR: #45028