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;