diff --git a/doc/classes/SoftBody.xml b/doc/classes/SoftBody.xml
index c912165e0b4..31d8d164ffb 100644
--- a/doc/classes/SoftBody.xml
+++ b/doc/classes/SoftBody.xml
@@ -96,6 +96,9 @@
[NodePath] to a [CollisionObject] this SoftBody should avoid clipping.
+
+ If [code]true[/code], the [SoftBody] is simulated in physics. Can be set to [code]false[/code] to pause the physics simulation.
+
diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp
index 7e3ec1ac7b8..931b897c0cb 100644
--- a/scene/3d/soft_body.cpp
+++ b/scene/3d/soft_body.cpp
@@ -308,6 +308,9 @@ void SoftBody::_notification(int p_what) {
void SoftBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("_draw_soft_mesh"), &SoftBody::_draw_soft_mesh);
+ ClassDB::bind_method(D_METHOD("set_physics_enabled", "enabled"), &SoftBody::set_physics_enabled);
+ ClassDB::bind_method(D_METHOD("is_physics_enabled"), &SoftBody::is_physics_enabled);
+
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody::get_collision_mask);
@@ -357,6 +360,8 @@ void SoftBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &SoftBody::set_ray_pickable);
ClassDB::bind_method(D_METHOD("is_ray_pickable"), &SoftBody::is_ray_pickable);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_enabled"), "set_physics_enabled", "is_physics_enabled");
+
ADD_GROUP("Collision", "collision_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
@@ -448,7 +453,7 @@ void SoftBody::prepare_physics_server() {
return;
}
- if (get_mesh().is_valid()) {
+ if (get_mesh().is_valid() && physics_enabled) {
become_mesh_owner();
PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
VS::get_singleton()->connect("frame_pre_draw", this, "_draw_soft_mesh");
@@ -547,6 +552,22 @@ const NodePath &SoftBody::get_parent_collision_ignore() const {
return parent_collision_ignore;
}
+void SoftBody::set_physics_enabled(bool p_enabled) {
+ if (p_enabled == physics_enabled) {
+ return;
+ }
+
+ physics_enabled = p_enabled;
+
+ if (is_inside_tree()) {
+ prepare_physics_server();
+ }
+}
+
+bool SoftBody::is_physics_enabled() const {
+ return physics_enabled;
+}
+
void SoftBody::set_pinned_points_indices(PoolVector p_pinned_points_indices) {
pinned_points = p_pinned_points_indices;
PoolVector::Read w = pinned_points.read();
diff --git a/scene/3d/soft_body.h b/scene/3d/soft_body.h
index a122895e0d3..437889b8c60 100644
--- a/scene/3d/soft_body.h
+++ b/scene/3d/soft_body.h
@@ -82,6 +82,8 @@ private:
RID physics_rid;
+ bool physics_enabled = true;
+
bool mesh_owner;
uint32_t collision_mask;
uint32_t collision_layer;
@@ -137,6 +139,9 @@ public:
void set_parent_collision_ignore(const NodePath &p_parent_collision_ignore);
const NodePath &get_parent_collision_ignore() const;
+ void set_physics_enabled(bool p_enabled);
+ bool is_physics_enabled() const;
+
void set_pinned_points_indices(PoolVector p_pinned_points_indices);
PoolVector get_pinned_points_indices();