Merge pull request #88946 from lawnjelly/fix_physics_on_floor_body
[3.x] Fix physics `on_floor_body` crash
This commit is contained in:
commit
ea68c2bfab
2 changed files with 25 additions and 11 deletions
|
@ -1077,9 +1077,17 @@ Vector3 KinematicBody::_move_and_slide_internal(const Vector3 &p_linear_velocity
|
||||||
float delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
|
float delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
|
||||||
|
|
||||||
Vector3 current_floor_velocity = floor_velocity;
|
Vector3 current_floor_velocity = floor_velocity;
|
||||||
if (on_floor && on_floor_body.is_valid()) {
|
|
||||||
// This approach makes sure there is less delay between the actual body velocity and the one we saved.
|
if (on_floor && on_floor_body_rid.is_valid()) {
|
||||||
PhysicsDirectBodyState *bs = PhysicsServer::get_singleton()->body_get_direct_state(on_floor_body);
|
PhysicsDirectBodyState *bs = nullptr;
|
||||||
|
|
||||||
|
// We need to check the on_floor_body still exists before accessing.
|
||||||
|
// A valid RID is no guarantee that the object has not been deleted.
|
||||||
|
if (ObjectDB::get_instance(on_floor_body_id)) {
|
||||||
|
// This approach makes sure there is less delay between the actual body velocity and the one we saved.
|
||||||
|
bs = PhysicsServer::get_singleton()->body_get_direct_state(on_floor_body_rid);
|
||||||
|
}
|
||||||
|
|
||||||
if (bs) {
|
if (bs) {
|
||||||
Transform gt = get_global_transform();
|
Transform gt = get_global_transform();
|
||||||
Vector3 local_position = gt.origin - bs->get_transform().origin;
|
Vector3 local_position = gt.origin - bs->get_transform().origin;
|
||||||
|
@ -1087,7 +1095,8 @@ Vector3 KinematicBody::_move_and_slide_internal(const Vector3 &p_linear_velocity
|
||||||
} else {
|
} else {
|
||||||
// Body is removed or destroyed, invalidate floor.
|
// Body is removed or destroyed, invalidate floor.
|
||||||
current_floor_velocity = Vector3();
|
current_floor_velocity = Vector3();
|
||||||
on_floor_body = RID();
|
on_floor_body_rid = RID();
|
||||||
|
on_floor_body_id = ObjectID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,17 +1107,18 @@ Vector3 KinematicBody::_move_and_slide_internal(const Vector3 &p_linear_velocity
|
||||||
floor_normal = Vector3();
|
floor_normal = Vector3();
|
||||||
floor_velocity = Vector3();
|
floor_velocity = Vector3();
|
||||||
|
|
||||||
if (current_floor_velocity != Vector3() && on_floor_body.is_valid()) {
|
if (current_floor_velocity != Vector3() && on_floor_body_rid.is_valid()) {
|
||||||
Collision floor_collision;
|
Collision floor_collision;
|
||||||
Set<RID> exclude;
|
Set<RID> exclude;
|
||||||
exclude.insert(on_floor_body);
|
exclude.insert(on_floor_body_rid);
|
||||||
if (move_and_collide(current_floor_velocity * delta, p_infinite_inertia, floor_collision, true, false, false, exclude)) {
|
if (move_and_collide(current_floor_velocity * delta, p_infinite_inertia, floor_collision, true, false, false, exclude)) {
|
||||||
colliders.push_back(floor_collision);
|
colliders.push_back(floor_collision);
|
||||||
_set_collision_direction(floor_collision, up_direction, p_floor_max_angle);
|
_set_collision_direction(floor_collision, up_direction, p_floor_max_angle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
on_floor_body = RID();
|
on_floor_body_rid = RID();
|
||||||
|
on_floor_body_id = ObjectID();
|
||||||
Vector3 motion = body_velocity * delta;
|
Vector3 motion = body_velocity * delta;
|
||||||
|
|
||||||
// No sliding on first attempt to keep floor motion stable when possible,
|
// No sliding on first attempt to keep floor motion stable when possible,
|
||||||
|
@ -1186,7 +1196,8 @@ Vector3 KinematicBody::_move_and_slide_internal(const Vector3 &p_linear_velocity
|
||||||
if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
|
||||||
on_floor = true;
|
on_floor = true;
|
||||||
floor_normal = col.normal;
|
floor_normal = col.normal;
|
||||||
on_floor_body = col.collider_rid;
|
on_floor_body_rid = col.collider_rid;
|
||||||
|
on_floor_body_id = col.collider;
|
||||||
floor_velocity = col.collider_vel;
|
floor_velocity = col.collider_vel;
|
||||||
if (p_stop_on_slope) {
|
if (p_stop_on_slope) {
|
||||||
// move and collide may stray the object a bit because of pre un-stucking,
|
// move and collide may stray the object a bit because of pre un-stucking,
|
||||||
|
@ -1237,7 +1248,8 @@ void KinematicBody::_set_collision_direction(const Collision &p_collision, const
|
||||||
if (Math::acos(p_collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
|
if (Math::acos(p_collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
|
||||||
on_floor = true;
|
on_floor = true;
|
||||||
floor_normal = p_collision.normal;
|
floor_normal = p_collision.normal;
|
||||||
on_floor_body = p_collision.collider_rid;
|
on_floor_body_rid = p_collision.collider_rid;
|
||||||
|
on_floor_body_id = p_collision.collider;
|
||||||
floor_velocity = p_collision.collider_vel;
|
floor_velocity = p_collision.collider_vel;
|
||||||
} else if (Math::acos(p_collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
|
} else if (Math::acos(p_collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
|
||||||
on_ceiling = true;
|
on_ceiling = true;
|
||||||
|
@ -1429,7 +1441,8 @@ void KinematicBody::_notification(int p_what) {
|
||||||
|
|
||||||
// Reset move_and_slide() data.
|
// Reset move_and_slide() data.
|
||||||
on_floor = false;
|
on_floor = false;
|
||||||
on_floor_body = RID();
|
on_floor_body_rid = RID();
|
||||||
|
on_floor_body_id = ObjectID();
|
||||||
on_ceiling = false;
|
on_ceiling = false;
|
||||||
on_wall = false;
|
on_wall = false;
|
||||||
colliders.clear();
|
colliders.clear();
|
||||||
|
|
|
@ -292,7 +292,8 @@ private:
|
||||||
|
|
||||||
Vector3 floor_normal;
|
Vector3 floor_normal;
|
||||||
Vector3 floor_velocity;
|
Vector3 floor_velocity;
|
||||||
RID on_floor_body;
|
RID on_floor_body_rid;
|
||||||
|
ObjectID on_floor_body_id;
|
||||||
bool on_floor;
|
bool on_floor;
|
||||||
bool on_ceiling;
|
bool on_ceiling;
|
||||||
bool on_wall;
|
bool on_wall;
|
||||||
|
|
Loading…
Reference in a new issue