summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
authorCamille Mohr-Daurat <pouleyKetchoup@gmail.com>2021-09-30 18:05:52 -0700
committerGitHub <noreply@github.com>2021-09-30 18:05:52 -0700
commit95432893e215686561c7064751f3369512409d66 (patch)
treef04d895282b5f568d26d8df3865a0e0af57b8f4a /scene/2d
parent77721b35ba21f2e7e8bb42cf415fccb018517843 (diff)
parent3fa76dfe5886fc25ede5a3da9d3bd95eff48f181 (diff)
Merge pull request #53272 from fabriceci/bug-platform-ceiling
Fix #53255 when a body gets stuck when it hits a descending platform in 2D/3D
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/physics_body_2d.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 3c25f99ada..5f56f86029 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1131,6 +1131,8 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
bool sliding_enabled = !floor_stop_on_slope;
// Constant speed can be applied only the first time sliding is enabled.
bool can_apply_constant_speed = sliding_enabled;
+ // If the platform's ceiling push down the body.
+ bool apply_ceiling_velocity = false;
bool first_slide = true;
bool vel_dir_facing_up = motion_velocity.dot(up_direction) > 0;
Vector2 last_travel;
@@ -1147,6 +1149,19 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
motion_results.push_back(result);
_set_collision_direction(result);
+ // If we hit a ceiling platform, we set the vertical motion_velocity to at least the platform one.
+ if (on_ceiling && result.collider_velocity != Vector2() && result.collider_velocity.dot(up_direction) < 0) {
+ // If ceiling sliding is on, only apply when the ceiling is flat or when the motion is upward.
+ if (!slide_on_ceiling || motion.dot(up_direction) < 0 || (result.collision_normal + up_direction).length() < 0.01) {
+ apply_ceiling_velocity = true;
+ Vector2 ceiling_vertical_velocity = up_direction * up_direction.dot(result.collider_velocity);
+ Vector2 motion_vertical_velocity = up_direction * up_direction.dot(motion_velocity);
+ if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) {
+ motion_velocity = ceiling_vertical_velocity + motion_velocity.slide(up_direction);
+ }
+ }
+ }
+
if (on_floor && floor_stop_on_slope && (motion_velocity.normalized() + up_direction).length() < 0.01) {
Transform2D gt = get_global_transform();
if (result.travel.length() <= margin + CMP_EPSILON) {
@@ -1200,7 +1215,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
motion = motion_slide_norm * (motion_slide_up.length() - result.travel.slide(up_direction).length() - last_travel.slide(up_direction).length());
}
// Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling.
- else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up)) {
+ else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up) && !apply_ceiling_velocity) {
Vector2 slide_motion = result.remainder.slide(result.collision_normal);
if (slide_motion.dot(motion_velocity) > 0.0) {
motion = slide_motion;