Skip to content

Add set_velocity and get_particles_rid to GPUParticles2D and GPUParticles3D #12497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
orolyn opened this issue May 25, 2025 · 0 comments
Open

Comments

@orolyn
Copy link

orolyn commented May 25, 2025

Describe the project you are working on

A 2D space game

Describe the problem or limitation you are having in your project

I create particle effects and add them to the tree on events such as a missile exploding. The missile itself is removed from the tree while the particles are added to the parent with one shot finished events for self removal.

The problem here is that the particles inherited velocity is zero and there is no way to change this with node based particles.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

RenderingServer::particles_set_emitter_velocity is precisely the tool needed to update the velocity manually when the particles are created, however this only works on the particles RID which the node do not expose.

I propose that both the particles RID be exposed, and a new method set_velocity be added to the node.
A similar implementation would exist for 3D particles as well.

diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index f9806c3ebf..1cde121c12 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -391,6 +391,11 @@ Rect2 GPUParticles2D::capture_rect() const {
        return r;
 }

+void GPUParticles2D::set_velocity(const Vector2 &p_velocity2d) const {
+       Vector3 velocity = Vector3(p_velocity2d.x, p_velocity2d.y, 0);
+       RS::get_singleton()->particles_set_emitter_velocity(particles, velocity);
+}
+
 void GPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) {
        if (texture.is_valid()) {
                texture->disconnect_changed(callable_mp(this, &GPUParticles2D::_texture_changed));
@@ -859,6 +864,9 @@ void GPUParticles2D::_bind_methods() {
        ClassDB::bind_method(D_METHOD("set_seed", "seed"), &GPUParticles2D::set_seed);
        ClassDB::bind_method(D_METHOD("get_seed"), &GPUParticles2D::get_seed);

+       ClassDB::bind_method(D_METHOD("get_particles_rid"), &GPUParticles2D::get_particles_rid);
+       ClassDB::bind_method(D_METHOD("set_velocity"), &GPUParticles2D::set_velocity);
+
        ADD_SIGNAL(MethodInfo("finished"));

        ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting", PROPERTY_HINT_ONESHOT), "set_emitting", "is_emitting");
diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h
index ca832698c1..2c408484e2 100644
--- a/scene/2d/gpu_particles_2d.h
+++ b/scene/2d/gpu_particles_2d.h
@@ -194,6 +194,12 @@ public:
        Rect2 capture_rect() const;
        void convert_from_particles(Node *p_particles);

+       _FORCE_INLINE_ RID get_particles_rid() const {
+               return particles;
+       }
+
+       void set_velocity(const Vector2 &p_velocity2d) const;
+
        GPUParticles2D();
        ~GPUParticles2D();
 };

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I am using this in my fork of godot, but I would prefer this to be in the official godot engine.

        // in Missile class
        var explosion = Scenes.Instantiate<MissileExplosion>();
        explosion.GlobalTransform = GlobalTransform;
        explosion.SetVelocity(Velocity); // set_velocity
        GetParent().AddChild(explosion);

If this enhancement will not be used often, can it be worked around with a few lines of script?

The feature may be used often, especially the part concerning exposure of the RID.

Is there a reason why this should be core and not an add-on in the asset library?

I had attempted to do this as a GDExtension however GPUParticles2D "particles" is only privately accessible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants