浏览代码

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.
Milan Davidovic 6 年之前
父节点
当前提交
c12ce2b4dd
共有 3 个文件被更改,包括 21 次插入0 次删除
  1. 8 0
      scene/2d/physics_body_2d.cpp
  2. 12 0
      scene/3d/physics_body.cpp
  3. 1 0
      scene/3d/physics_body.h

+ 8 - 0
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) {

+ 12 - 0
scene/3d/physics_body.cpp

@@ -1387,6 +1387,18 @@ Ref<KinematicCollision> 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));

+ 1 - 0
scene/3d/physics_body.h

@@ -314,6 +314,7 @@ private:
 	Ref<KinematicCollision> _get_slide_collision(int p_bounce);
 
 protected:
+	void _notification(int p_what);
 	static void _bind_methods();
 
 public: