diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml
index c6b39c9941d..dcf533d884c 100644
--- a/doc/classes/CPUParticles2D.xml
+++ b/doc/classes/CPUParticles2D.xml
@@ -172,6 +172,12 @@
The rectangle's extents if [member emission_shape] is set to [constant EMISSION_SHAPE_RECTANGLE].
+
+ The ring's inner radius if [member emission_shape] is set to [constant EMISSION_SHAPE_RING].
+
+
+ The ring's outer radius if [member emission_shape] is set to [constant EMISSION_SHAPE_RING].
+
Particles will be emitted inside this region.
@@ -385,7 +391,10 @@
Particles will be emitted at a position chosen randomly among [member emission_points]. Particle velocity and rotation will be set based on [member emission_normals]. Particle color will be modulated by [member emission_colors].
-
+
+ Particles will be emitted in the area of a ring parameterized by its outer and inner radius.
+
+
Represents the size of the [enum EmissionShape] enum.
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 592fb138bb7..c897a5b7004 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -524,6 +524,14 @@ void CPUParticles2D::set_emission_colors(const Vector &p_colors) {
emission_colors = p_colors;
}
+void CPUParticles2D::set_emission_ring_inner_radius(real_t p_inner_radius) {
+ emission_ring_inner_radius = p_inner_radius;
+}
+
+void CPUParticles2D::set_emission_ring_radius(real_t p_ring_radius) {
+ emission_ring_radius = p_ring_radius;
+}
+
real_t CPUParticles2D::get_emission_sphere_radius() const {
return emission_sphere_radius;
}
@@ -544,6 +552,14 @@ Vector CPUParticles2D::get_emission_colors() const {
return emission_colors;
}
+real_t CPUParticles2D::get_emission_ring_inner_radius() const {
+ return emission_ring_inner_radius;
+}
+
+real_t CPUParticles2D::get_emission_ring_radius() const {
+ return emission_ring_radius;
+}
+
CPUParticles2D::EmissionShape CPUParticles2D::get_emission_shape() const {
return emission_shape;
}
@@ -647,6 +663,13 @@ void CPUParticles2D::_validate_property(PropertyInfo &p_property) const {
p_property.usage = PROPERTY_USAGE_NONE;
}
+ if (p_property.name == "emission_ring_inner_radius" && emission_shape != EMISSION_SHAPE_RING) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
+ if (p_property.name == "emission_ring_radius" && emission_shape != EMISSION_SHAPE_RING) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
+
if (p_property.name == "seed" && !use_fixed_seed) {
p_property.usage = PROPERTY_USAGE_NONE;
}
@@ -926,6 +949,13 @@ void CPUParticles2D::_particles_process(double p_delta) {
p.base_color = emission_colors.get(random_idx);
}
} break;
+ case EMISSION_SHAPE_RING: {
+ real_t t = Math::TAU * Math::randf();
+ real_t outer_sq = emission_ring_radius * emission_ring_radius;
+ real_t inner_sq = emission_ring_inner_radius * emission_ring_inner_radius;
+ real_t radius = Math::sqrt(Math::randf() * (outer_sq - inner_sq) + inner_sq);
+ p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
+ } break;
case EMISSION_SHAPE_MAX: { // Max value for validity check.
break;
}
@@ -1379,6 +1409,9 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
Vector2 rect_extents = Vector2(proc_mat->get_emission_box_extents().x, proc_mat->get_emission_box_extents().y);
set_emission_rect_extents(rect_extents);
+ set_emission_ring_radius(proc_mat->get_emission_ring_radius());
+ set_emission_ring_inner_radius(proc_mat->get_emission_ring_inner_radius());
+
Ref scale3D = proc_mat->get_param_texture(ParticleProcessMaterial::PARAM_SCALE);
if (scale3D.is_valid()) {
split_scale = true;
@@ -1527,6 +1560,12 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_emission_colors", "array"), &CPUParticles2D::set_emission_colors);
ClassDB::bind_method(D_METHOD("get_emission_colors"), &CPUParticles2D::get_emission_colors);
+ ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &CPUParticles2D::set_emission_ring_inner_radius);
+ ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &CPUParticles2D::get_emission_ring_inner_radius);
+
+ ClassDB::bind_method(D_METHOD("set_emission_ring_radius", "radius"), &CPUParticles2D::set_emission_ring_radius);
+ ClassDB::bind_method(D_METHOD("get_emission_ring_radius"), &CPUParticles2D::get_emission_ring_radius);
+
ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles2D::get_gravity);
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles2D::set_gravity);
@@ -1544,12 +1583,14 @@ void CPUParticles2D::_bind_methods() {
ADD_SIGNAL(MethodInfo("finished"));
ADD_GROUP("Emission Shape", "emission_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Rectangle,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Rectangle,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,suffix:px"), "set_emission_sphere_radius", "get_emission_sphere_radius");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "emission_rect_extents", PROPERTY_HINT_NONE, "suffix:px"), "set_emission_rect_extents", "get_emission_rect_extents");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_inner_radius"), "set_emission_ring_inner_radius", "get_emission_ring_inner_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_radius"), "set_emission_ring_radius", "get_emission_ring_radius");
ADD_GROUP("Particle Flags", "particle_flag_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY);
ADD_GROUP("Direction", "");
@@ -1638,6 +1679,7 @@ void CPUParticles2D::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_RECTANGLE);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
+ BIND_ENUM_CONSTANT(EMISSION_SHAPE_RING);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);
}
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index b9310c95d64..f1554c2708a 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -75,7 +75,8 @@ public:
EMISSION_SHAPE_RECTANGLE,
EMISSION_SHAPE_POINTS,
EMISSION_SHAPE_DIRECTED_POINTS,
- EMISSION_SHAPE_MAX
+ EMISSION_SHAPE_RING,
+ EMISSION_SHAPE_MAX,
};
private:
@@ -178,6 +179,8 @@ private:
Vector emission_normals;
Vector emission_colors;
int emission_point_count = 0;
+ real_t emission_ring_inner_radius = 0.8;
+ real_t emission_ring_radius = 1.0;
Ref scale_curve_x;
Ref scale_curve_y;
@@ -307,6 +310,8 @@ public:
void set_emission_points(const Vector &p_points);
void set_emission_normals(const Vector &p_normals);
void set_emission_colors(const Vector &p_colors);
+ void set_emission_ring_inner_radius(real_t p_inner_radius);
+ void set_emission_ring_radius(real_t p_ring_radius);
void set_scale_curve_x(Ref p_scale_curve);
void set_scale_curve_y(Ref p_scale_curve);
void set_split_scale(bool p_split_scale);
@@ -317,6 +322,8 @@ public:
Vector get_emission_points() const;
Vector get_emission_normals() const;
Vector get_emission_colors() const;
+ real_t get_emission_ring_inner_radius() const;
+ real_t get_emission_ring_radius() const;
Ref get_scale_curve_x() const;
Ref get_scale_curve_y() const;
bool get_split_scale();
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index ea9a0e69493..adc095c1f04 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -557,6 +557,9 @@ void GPUParticles2D::convert_from_particles(Node *p_particles) {
proc_mat->set_emission_shape(ParticleProcessMaterial::EmissionShape(cpu_particles->get_emission_shape()));
proc_mat->set_emission_sphere_radius(cpu_particles->get_emission_sphere_radius());
+ proc_mat->set_emission_ring_radius(cpu_particles->get_emission_ring_radius());
+ proc_mat->set_emission_ring_inner_radius(cpu_particles->get_emission_ring_inner_radius());
+
Vector2 rect_extents = cpu_particles->get_emission_rect_extents();
proc_mat->set_emission_box_extents(Vector3(rect_extents.x, rect_extents.y, 0));