diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml index bce1a805269..ca1948e8e11 100644 --- a/doc/classes/PhysicalBone3D.xml +++ b/doc/classes/PhysicalBone3D.xml @@ -5,6 +5,7 @@ The [PhysicalBone3D] node is a physics body that can be used to make bones in a [Skeleton3D] react to physics. + [b]Note:[/b] In order to detect physical bones with raycasts, the [member SkeletonModifier3D.active] property of the parent [PhysicalBoneSimulator3D] must be [code]true[/code] and the [Skeleton3D]'s bone must be assigned to [PhysicalBone3D] correctly; it means that [method get_bone_id] should return a valid id ([code]>= 0[/code]). diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index 1167b70c8d2..5829a787a15 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -243,6 +243,8 @@ + This method exists for compatibility with old structures in which the [Skeleton3D] does not have a [PhysicalBoneSimulator3D] as a child, but directly has [PhysicalBone3D]s as children. + In case you need to raycast to it without running [method physical_bones_start_simulation], call this method with [code]enabled == true[/code]. diff --git a/scene/3d/physics/physical_bone_3d.cpp b/scene/3d/physics/physical_bone_3d.cpp index c290f16c0d9..294690a89a0 100644 --- a/scene/3d/physics/physical_bone_3d.cpp +++ b/scene/3d/physics/physical_bone_3d.cpp @@ -764,7 +764,7 @@ void PhysicalBone3D::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { PhysicalBoneSimulator3D *simulator = get_simulator(); if (simulator) { - if (-1 != bone_id) { + if (bone_id != -1) { simulator->unbind_physical_bone_from_bone(bone_id); bone_id = -1; } @@ -816,7 +816,7 @@ void PhysicalBone3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) { PhysicalBoneSimulator3D *simulator = get_simulator(); Skeleton3D *skeleton = get_skeleton(); if (simulator && skeleton) { - if (-1 != bone_id) { + if (bone_id != -1) { simulator->set_bone_global_pose(bone_id, skeleton->get_global_transform().affine_inverse() * (global_transform * body_offset_inverse)); } } @@ -1293,7 +1293,7 @@ void PhysicalBone3D::update_bone_id() { const int new_bone_id = simulator->find_bone(bone_name); if (new_bone_id != bone_id) { - if (-1 != bone_id) { + if (bone_id != -1) { // Assert the unbind from old node simulator->unbind_physical_bone_from_bone(bone_id); } @@ -1313,7 +1313,7 @@ void PhysicalBone3D::update_offset() { Skeleton3D *skeleton = get_skeleton(); if (simulator && skeleton) { Transform3D bone_transform(skeleton->get_global_transform()); - if (-1 != bone_id) { + if (bone_id != -1) { bone_transform *= simulator->get_bone_global_pose(bone_id); } @@ -1328,7 +1328,7 @@ void PhysicalBone3D::update_offset() { } void PhysicalBone3D::_start_physics_simulation() { - if (_internal_simulate_physics || !simulator_id.is_valid()) { + if (_internal_simulate_physics || !simulator_id.is_valid() || bone_id == -1) { return; } reset_to_rest_position(); @@ -1344,7 +1344,7 @@ void PhysicalBone3D::_start_physics_simulation() { void PhysicalBone3D::_stop_physics_simulation() { PhysicalBoneSimulator3D *simulator = get_simulator(); if (simulator) { - if (simulator->is_simulating_physics()) { + if (simulator->is_active() && bone_id != -1) { set_body_mode(PhysicsServer3D::BODY_MODE_KINEMATIC); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 7c9fbd3b6de..b5263add48b 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -1140,7 +1140,8 @@ void Skeleton3D::set_animate_physical_bones(bool p_enabled) { if (!sim) { return; } - sim->set_active(p_enabled); + animate_physical_bones = p_enabled; + sim->set_active(animate_physical_bones || sim->is_simulating_physics()); } bool Skeleton3D::get_animate_physical_bones() const { @@ -1148,7 +1149,7 @@ bool Skeleton3D::get_animate_physical_bones() const { if (!sim) { return false; } - return sim->is_active(); + return animate_physical_bones; } void Skeleton3D::physical_bones_stop_simulation() { @@ -1157,7 +1158,7 @@ void Skeleton3D::physical_bones_stop_simulation() { return; } sim->physical_bones_stop_simulation(); - sim->set_active(false); + sim->set_active(animate_physical_bones || sim->is_simulating_physics()); } void Skeleton3D::physical_bones_start_simulation_on(const TypedArray &p_bones) { diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index eef7c9318d7..2d70aafcadb 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -67,6 +67,7 @@ class Skeleton3D : public Node3D { GDCLASS(Skeleton3D, Node3D); #ifndef DISABLE_DEPRECATED + bool animate_physical_bones = false; Node *simulator = nullptr; void setup_simulator(); #endif // _DISABLE_DEPRECATED