Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix errors in CharacterBody when floor is destroyed or removed #54820

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/classes/PhysicsServer2D.xml
Original file line number Diff line number Diff line change
@@ -346,7 +346,7 @@
<return type="PhysicsDirectBodyState2D" />
<argument index="0" name="body" type="RID" />
<description>
Returns the [PhysicsDirectBodyState2D] of the body.
Returns the [PhysicsDirectBodyState2D] of the body. Returns [code]null[/code] if the body is destroyed or removed from the physics space.
</description>
</method>
<method name="body_get_max_contacts_reported" qualifiers="const">
2 changes: 1 addition & 1 deletion doc/classes/PhysicsServer3D.xml
Original file line number Diff line number Diff line change
@@ -320,7 +320,7 @@
<return type="PhysicsDirectBodyState3D" />
<argument index="0" name="body" type="RID" />
<description>
Returns the [PhysicsDirectBodyState3D] of the body.
Returns the [PhysicsDirectBodyState3D] of the body. Returns [code]null[/code] if the body is destroyed or removed from the physics space.
</description>
</method>
<method name="body_get_max_contacts_reported" qualifiers="const">
9 changes: 9 additions & 0 deletions modules/bullet/bullet_physics_server.cpp
Original file line number Diff line number Diff line change
@@ -837,8 +837,17 @@ void BulletPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) {
}

PhysicsDirectBodyState3D *BulletPhysicsServer3D::body_get_direct_state(RID p_body) {
if (!rigid_body_owner.owns(p_body)) {
return nullptr;
}

RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, nullptr);

if (!body->get_space()) {
return nullptr;
}

return BulletPhysicsDirectBodyState3D::get_singleton(body);
}

4 changes: 4 additions & 0 deletions scene/2d/physics_body_2d.cpp
Original file line number Diff line number Diff line change
@@ -1101,6 +1101,10 @@ bool CharacterBody2D::move_and_slide() {
if (bs) {
Vector2 local_position = gt.elements[2] - bs->get_transform().elements[2];
current_platform_velocity = bs->get_velocity_at_local_position(local_position);
} else {
// Body is removed or destroyed, invalidate floor.
current_platform_velocity = Vector2();
platform_rid = RID();
}
} else {
current_platform_velocity = Vector2();
4 changes: 4 additions & 0 deletions scene/3d/physics_body_3d.cpp
Original file line number Diff line number Diff line change
@@ -1145,6 +1145,10 @@ bool CharacterBody3D::move_and_slide() {
if (bs) {
Vector3 local_position = gt.origin - bs->get_transform().origin;
current_platform_velocity = bs->get_velocity_at_local_position(local_position);
} else {
// Body is removed or destroyed, invalidate floor.
current_platform_velocity = Vector3();
platform_rid = RID();
}
} else {
current_platform_velocity = Vector3();
9 changes: 8 additions & 1 deletion servers/physics_2d/godot_physics_server_2d.cpp
Original file line number Diff line number Diff line change
@@ -963,10 +963,17 @@ bool GodotPhysicsServer2D::body_test_motion(RID p_body, const MotionParameters &
PhysicsDirectBodyState2D *GodotPhysicsServer2D::body_get_direct_state(RID p_body) {
ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");

if (!body_owner.owns(p_body)) {
return nullptr;
}

GodotBody2D *body = body_owner.get_or_null(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.");

return body->get_direct_state();
9 changes: 8 additions & 1 deletion servers/physics_3d/godot_physics_server_3d.cpp
Original file line number Diff line number Diff line change
@@ -881,10 +881,17 @@ bool GodotPhysicsServer3D::body_test_motion(RID p_body, const MotionParameters &
PhysicsDirectBodyState3D *GodotPhysicsServer3D::body_get_direct_state(RID p_body) {
ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");

if (!body_owner.owns(p_body)) {
return nullptr;
}

GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_NULL_V(body, nullptr);

ERR_FAIL_NULL_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.");

return body->get_direct_state();