From c12ce2b4ddaf22cb06b69a8d0c685b54485e8c05 Mon Sep 17 00:00:00 2001 From: Milan Davidovic Date: Mon, 19 Aug 2019 11:11:14 +0200 Subject: Prevent move_and_slide() to generate an error. When moving KinematicBody2D from one scene to another and not freeing the old scene, the first call to move_and_slide() in the new scene will generate an error because KinematicBody2D keeps internaly a RID on_floor_body of a body resource in the old scene which no more has a space assigned. To fix this, on_floor_body is set to empty RID in response to NOTIFICATION_ENTER_TREE notification of KinematicBody2D and KinematicBody. Also all other data related to move_and_slide() is reset: floor, ceiling, wall flags, colliders vector, floor_velocity. This fixes #31416. --- scene/2d/physics_body_2d.cpp | 8 ++++++++ scene/3d/physics_body.cpp | 12 ++++++++++++ scene/3d/physics_body.h | 1 + 3 files changed, 21 insertions(+) diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 49da709a47..ec4545c3a0 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1446,6 +1446,14 @@ void KinematicBody2D::_direct_state_changed(Object *p_state) { void KinematicBody2D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { last_valid_transform = get_global_transform(); + + // Reset move_and_slide() data. + on_floor = false; + on_floor_body = RID(); + on_ceiling = false; + on_wall = false; + colliders.clear(); + floor_velocity = Vector2(); } if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 19d5f1dd3c..3c52547bf1 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1387,6 +1387,18 @@ Ref KinematicBody::_get_slide_collision(int p_bounce) { return slide_colliders[p_bounce]; } +void KinematicBody::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE) { + // Reset move_and_slide() data. + on_floor = false; + on_floor_body = RID(); + on_ceiling = false; + on_wall = false; + colliders.clear(); + floor_velocity = Vector3(); + } +} + void KinematicBody::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index aa6030d44e..7db7da6086 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -314,6 +314,7 @@ private: Ref _get_slide_collision(int p_bounce); protected: + void _notification(int p_what); static void _bind_methods(); public: -- cgit v1.2.3