Skip to content
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

GPUParticles2D: Oneshot Sub Emitter won't emit finished() signal #93546

Open
4X3L82 opened this issue Jun 24, 2024 · 4 comments
Open

GPUParticles2D: Oneshot Sub Emitter won't emit finished() signal #93546

4X3L82 opened this issue Jun 24, 2024 · 4 comments

Comments

@4X3L82
Copy link

4X3L82 commented Jun 24, 2024

Tested versions

  • Reproducible in: v4.2.1.stable.official [b09f793] and v4.3.beta2.official [b75f048]

System information

Godot v4.3.beta2 - Manjaro Linux #1 SMP PREEMPT_DYNAMIC Mon May 27 03:41:25 UTC 2024 - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3080 Laptop GPU - AMD Ryzen 9 5900HX with Radeon Graphics (16 Threads)

Issue description

I've created a simple GPUParticles2D effect with a main+subemitter, both set to OneShot and I want to know when the whole effect is done. I want to know when it's done so I can then destroy the effect (cleaning up). This could be done by using the finished() signal of the subemitter, however, it's never emitted.

Goal:
I need the finished() signal from the oneshot subemitter to know when the whole GPUParticles2D effect is done, so I can then call queue_free() to make it clean itself up.

Steps to reproduce

  • Create a GPUParticles2D object ("main") and set it to oneshot.
  • Create another GPUParticles2D object ("sub") (as child of the above) and set it to oneshot.
  • Set ("sub") as subemitter of ("main") and set the Sub Emitter Mode to "At End".
  • Connect the finished() signal of ("sub) to whatever function you want (like a print() statement)
  • Execute the script/emit the particles, and observe that the signal is never emitted

Minimal reproduction project (MRP)

subemitter_no_finished.zip

This MRP has a button to restart() the main emitter, and 2 print statements connected to the 2 finished() signals of the main and sub emitter. Once the button is pressed, you can see the particles doing their thing. At the end of the main emitter, two things happen: "main done!" is printed, and the subemitter kicks in. Then at the end of the subemitter, nothing happens.

I expected the finished() signal of the sub emitter to emit, which would then print "sub done!".

@4X3L82
Copy link
Author

4X3L82 commented Jul 7, 2024

Based on this comment by @patwork on a similar issue, I was able to resolve this:

I've added %sub.restart() just after the %main.restart() for the button. Now when the button is pressed, the emitter does its thing and both main & sub emitter send the finished() signal.

However, things still don't look/feel right to me. Basically, a double restart() to make a single effect work seems gratuitous.

Without the restart() on the sub-emitter, the whole particle effect (both main+sub) work fine. There's no (visual) feedback that the restart() is missing/required on the sub-emitter and not just main. Shouldn't the restart() on the main emitter trickle down and automatically fire off a restart() on its own sub-emitter(s)?
Or rephrased: Is there ever a case where you want to restart() the main emitter without restarting its sub-emitter(s)?

If all the above is fully expected behavior, including restart() not trickle down to its own sub-emitter(s), then I think me (and probably others too) would benefit from clearer documentation.

@patwork
Copy link
Contributor

patwork commented Jul 7, 2024

This case is different from the one described in #93991. I don't want to speak for the authors of the GPU Particles code, but in my opinion in that (not this) case is an oversight of a possible situation where the one_shot flag is set by the script when the particle emitter has been already added to the tree and passed its initialization.

💣 warning, below is just my current understanding, not confirmed by Godot devs

This case refers to something else, namely sub-emitters. The difference is that you do not have a problem with the finished signal in the main emitter, but in the sub-emitter that is triggered by it.

I was looking at the GPU Particles code for the first time yesterday so my conclusions are not necessarily 100% correct, but as far as I can see, sub-emitters do not send signals because they are never emitted on their own. In fact, the effect from a sub-emitter is "attached" to the renderer queue of the emitter that triggers it.

If you look in the scene's live-view debugger at the behavior of the emitters in your example, you'll see that the sub-emitter never changes its "Emitting" state, even when the results of its action start to appear on the screen. Therefore, if it is never emitted, it cannot return the finished flag.

This also confirms why you only received the finished signal when you manually started the sub-emitter using restart().

These are the words from the documentation:

When you set a particle system as the sub-emitter of another, the system stops emitting, even if the Emitting property was checked. Don't worry, it didn't break. This happens to every particle system as soon as it becomes a sub-emitter. You also won't be able to re-enable the property as long as the particle system is used as a sub-emitter.

Even though the parent particle system can be selected from the list of available particle systems, a particle system which is its own sub-emitter does not work in Godot. It will simply not spawn. The same is true for any other kind of recursive or self-referential sub-emitter setup.

https://docs.godotengine.org/pl/4.x/tutorials/3d/particles/subemitters.html

https://docs.godotengine.org/pl/4.x/tutorials/3d/particles/process_material_properties.html#doc-process-material-properties-subemitter

@4X3L82
Copy link
Author

4X3L82 commented Oct 3, 2024

@Calinou: Could this issue be added to this tracker?

@4X3L82
Copy link
Author

4X3L82 commented Oct 5, 2024

Potentially related proposal (might be the solution?).

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

3 participants