Browse Source

Fix RigidBody collision update after changing collision layer/mask

Changing the collision layer of a sleeping body was not triggering area
updates correctly.

Bodies need to be active for collision to be checked against already
overlapping bodies and areas.

Neighbors need to be activated too in order to handle the case where a
static body is modified (it can't be activated directly but paired
bodies need to check their collision again).

In 3D, moved the call to wakeup() from the physics server to
BodySW::_shapes_changed to make it consistent with 2D and also handle
the case where shapes are modified (_shapes_changed is called in both
this case and collision layer changes).
PouleyKetchoupp 3 năm trước cách đây
mục cha
commit
562d9cef1b

+ 2 - 0
servers/physics/body_sw.cpp

@@ -287,6 +287,8 @@ PhysicsServer::BodyMode BodySW::get_mode() const {
 
 void BodySW::_shapes_changed() {
 	_update_inertia();
+	wakeup();
+	wakeup_neighbours();
 }
 
 void BodySW::set_state(PhysicsServer::BodyState p_state, const Variant &p_variant) {

+ 0 - 2
servers/physics/physics_server_sw.cpp

@@ -578,7 +578,6 @@ void PhysicsServerSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
 	ERR_FAIL_COND(!body);
 
 	body->set_collision_layer(p_layer);
-	body->wakeup();
 }
 
 uint32_t PhysicsServerSW::body_get_collision_layer(RID p_body) const {
@@ -593,7 +592,6 @@ void PhysicsServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
 	ERR_FAIL_COND(!body);
 
 	body->set_collision_mask(p_mask);
-	body->wakeup();
 }
 
 uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body) const {

+ 1 - 0
servers/physics_2d/body_2d_sw.cpp

@@ -251,6 +251,7 @@ Physics2DServer::BodyMode Body2DSW::get_mode() const {
 
 void Body2DSW::_shapes_changed() {
 	_update_inertia();
+	wakeup();
 	wakeup_neighbours();
 }