godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.26k stars 20.23k forks source link

GPUParticles3D: Emitting with oneshot + explosiveness within editor doesn't work if triggered soon after 1st time. #79689

Closed cybernaut4 closed 1 year ago

cybernaut4 commented 1 year ago

Godot version

v4.1.1.stable.mono.official [bd6af8e0e]

System information

Godot v4.1.1.stable.mono - Windows 10.0.19044 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 Laptop GPU (NVIDIA; 31.0.15.3598) - AMD Ryzen 9 5900HX with Radeon Graphics (16 Threads)

Issue description

Situation

If One Shot checkbox is enabled, Emitting will uncheck itself after its lifetime. Normal procedure so far.

Problem

As soon as Emitting boolean is automatically unchecked, hitting it again will not work (it unchecks itself again, but the particles do not show). It seems you have to wait an additional amount of time on top of its Lifetime to preview its emission properly.

It wouldn't be a problem if the particle's Lifetime was less than a second. However, it's time-consuming with long-lasting particle emissions (eg. Lifetime >= 1.5s ). I can tell this extra delay is roughly proportional to the Lifetime value.

Example:

  1. Set Lifetime to 1.0s
  2. Set Emitting to true (particles spawned successfully)
  3. Emitting automatically sets to false after 1.0s
  4. (Wait twice its Lifetime since turning Emitting ON to expectedly emit again.)
  5. Set Emitting to true (particles spawned successfully again)
  6. Emitting automatically sets to false after 1.0s
  7. Set Emitting to true (it fails: close to zero or no particles emitted)

The 4th step has been mandatory ever since I started with Godot 3, regardless of hardware. Note that I'm running an arguable high-end computer and this still happens. At this point, I assume this is an engine issue.

Steps to reproduce

Case A: Without explosiveness

  1. New project
  2. Create GPUParticles3D with basic setup
    • Amount = 4
    • Time -> One Shot = ON
    • Time -> Lifetime = 1 (default)
    • Process Material -> New ParticleProcessMaterial
    • Draw Passes -> Pass 1 -> New QuadMesh
  3. Emitting = true
  4. Do it again, as soon as Emitting changes to false.

When activating Emitting a second time, immediately after it turns false, one of two happens: A. Spawns one or two particles, Emitting turns false immediately. B. No particle spawning at all, Emitting turns false abruptly.

Case B: Explosiveness ON

  1. Same steps above, with an additional in GPUParticles3D
    • Time -> Explosiveness = 1 (or higher values than 0.5)

When activating Emitting a second time, while done as soon as it was turned false automatically, no particle spawns at all and Emitting turns false with approx. same delay as Lifetime value. If you don't wait at least twice as long as its Lifetime before turning Emitting ON again, it will still not emit.

Minimal reproduction project

Godot411-GPUParticles3D-oneshot.zip

clayjohn commented 1 year ago

This is currently the expected behaviour for one_shot particles. I agree that the behaviour is confusing. This issue comes up a lot with new users especially.

For clarity, the extra delay is exactly the lifetime of the particle system when explosiveness is 0 and it decreases as explosiveness approaches 1. The delay is essentially the amount of time that a particle may survive after having been emitted. When explosiveness is 0, a particle may be emitted right when the lifetime is reached, and it may survive for a lifetime amount of time.

For 4.2, we merged https://github.com/godotengine/godot/pull/76859 which allows you to connect a signal to particles that will fire when the particle has finished (and thus you can enable emitting to restart the system).

That being said, for some users it seems that they expect that toggling emitting off and then on when using one_shot particles will restart the particle system. But currently, the way to restart a particle system is to call restart(). restart() will also kill any active particles, so it may not be the ideal solution.

We have been discussing recently whether we should change the behaviour of the emitting property to match user expectations better. The discussion is here: https://github.com/godotengine/godot-proposals/issues/7322

Since this isn't technically a bug, I encourage you to add your thoughts to https://github.com/godotengine/godot-proposals/issues/7322 so we can track the conversation in one place. Accordingly, I will be closing this bug report

cybernaut4 commented 1 year ago

For clarity, the extra delay is exactly the lifetime of the particle system when explosiveness is 0 and it decreases as explosiveness approaches 1. The delay is essentially the amount of time that a particle may survive after having been emitted.

Emitting turns to false automatically when no particle is alive, therefore it should emit as soon as Emitting is true again. But it's not emitting, and this is the issue here.

It doesn't make sense to wait twice the Lifetime of the particles to work if Emitting already switched to false on its own.

That being said, for some users it seems that they expect that toggling emitting off and then on when using one_shot particles will restart the particle system.

In my steps I have never toggled off Emitting. While it would be ideal to have for long-lasting particles, that's not the issue I'm addressing here. On the off-topic: it's good to know how far we can go with the current restart() route.

Since this isn't technically a bug, I encourage you to add your thoughts to https://github.com/godotengine/godot-proposals/issues/7322 so we can track the conversation in one place. Accordingly, I will be closing this bug report.

Let me rephrase the situation and problem:

This behavior is technically a bug here. There is no explanation in the docs stating that you have to wait an invisible amount of time (despite of the Emitting property being switched to false on its own) to make it work as expected.

Therefore, there is no reason to not call it a bug here.

While this way of operating doesn't seem to change anytime soon (Godot 4.2 plans seem to be set in "virtual stone"), I suggest to, at least, try resolving this matter for the time being.

cybernaut4 commented 1 year ago

This issue has been closed prematurely due to a misunderstanding.

I have provided further explanation. I hope this issue is reopened sooner.