diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml
index 175c43208038..64daea3539fe 100644
--- a/doc/classes/Physics2DServer.xml
+++ b/doc/classes/Physics2DServer.xml
@@ -348,7 +348,7 @@
- Returns the [Physics2DDirectBodyState] of the body.
+ Returns the [Physics2DDirectBodyState] of the body. Returns [code]null[/code] if the body is destroyed or removed from the physics space.
diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml
index 22e9f4b0358b..107a87412242 100644
--- a/doc/classes/PhysicsServer.xml
+++ b/doc/classes/PhysicsServer.xml
@@ -332,7 +332,7 @@
- Returns the [PhysicsDirectBodyState] of the body.
+ Returns the [PhysicsDirectBodyState] of the body. Returns [code]null[/code] if the body is destroyed or removed from the physics space.
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 820cc07b4949..a4344665b51e 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -851,8 +851,17 @@ bool BulletPhysicsServer::body_is_ray_pickable(RID p_body) const {
}
PhysicsDirectBodyState *BulletPhysicsServer::body_get_direct_state(RID p_body) {
+ if (!rigid_body_owner.owns(p_body)) {
+ return nullptr;
+ }
+
RigidBodyBullet *body = rigid_body_owner.get(p_body);
ERR_FAIL_COND_V(!body, nullptr);
+
+ if (!body->get_space()) {
+ return nullptr;
+ }
+
return BulletPhysicsDirectBodyState::get_singleton(body);
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 424ad75cc8d0..59eb41c4eca1 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1120,6 +1120,10 @@ Vector2 KinematicBody2D::_move_and_slide_internal(const Vector2 &p_linear_veloci
Transform2D gt = get_global_transform();
Vector2 local_position = gt.elements[2] - bs->get_transform().elements[2];
current_floor_velocity = bs->get_velocity_at_local_position(local_position);
+ } else {
+ // Body is removed or destroyed, invalidate floor.
+ current_floor_velocity = Vector2();
+ on_floor_body = RID();
}
}
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 82a5c42a67f8..18a0cff35114 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1074,6 +1074,10 @@ Vector3 KinematicBody::_move_and_slide_internal(const Vector3 &p_linear_velocity
Transform gt = get_global_transform();
Vector3 local_position = gt.origin - bs->get_transform().origin;
current_floor_velocity = bs->get_velocity_at_local_position(local_position);
+ } else {
+ // Body is removed or destroyed, invalidate floor.
+ current_floor_velocity = Vector3();
+ on_floor_body = RID();
}
}
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index c889d9187398..365b98472ea5 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -881,8 +881,17 @@ int PhysicsServerSW::body_test_ray_separation(RID p_body, const Transform &p_tra
}
PhysicsDirectBodyState *PhysicsServerSW::body_get_direct_state(RID p_body) {
+ if (!body_owner.owns(p_body)) {
+ return nullptr;
+ }
+
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, nullptr);
+
+ if (!body->get_space()) {
+ return nullptr;
+ }
+
ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");
direct_state->body = body;
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index eb526fe2ea47..21c9be258f5e 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -962,7 +962,11 @@ Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, nullptr);
- ERR_FAIL_COND_V(!body->get_space(), nullptr);
+
+ if (!body->get_space()) {
+ return nullptr;
+ }
+
ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");
direct_state->body = body;