Open HolonProduction opened 1 year ago
Would have to be very careful about interactions with animation player. It seems to be an on and off "regression" kind of thing, but sometimes it triggers bools every frame, sometimes only on switch. Furthermore I'm not sure restart is what we want here, because that kills all active particles, while i think that there's some cases where you may just want to restart it after a delay, but stilll letting the emitter finish to avoid things popping out of existence
I imagine the usecase is seeing your vfx in the editor without having to wait their "real" end in emitting toggle.
I suggest 2 things to this:
For me specifically I have my own implementation of oneshot that runs only in game because it's super annoying to work with when you're dealing with complex VFX scene.
2. A rework of oneshot that makes particles just start emitting if you toggle it on again before the time it has finished. I wouldn't necessarily reset. But also I really never use oneshot particle due to the problematic interaction with animation player, so if this doesn't work im fine with reset too.
I agree, though if possible it should've been done in a way that a reset isn't needed, OneShot should work to spawn particles at customized intervals defined by:
But currently as it is, especially with explosiveness values high, it doesn't work reliably.
The workaround I use today is to duplicate the GPUParticles3D node at runtime, make it unique then play that one. While this workaround gets the job done, it costs performance and is unsightly to think about. Furthermore, this method has very limited utility compared to the potential one GPUParticles3D node could've had:
If reliable, it could've spawn particles at intervals fully controlled by script, or when player manually toggles things, whether directly or via AnimationPlayer. GPUParticles3D today, in this case, isn't that much reliable.
Using a reset to re-emit OneShot particles would vanish the sparks before they hit the floor.
Unfortunately I have no idea how this could be done, as I'm not one with the Engine's code (nevermind C++) but I thought bringing up front the potential this system could've had would be worth noticing.
Is this suggesting that setting emitting = true
should work like resetting? So if set before the one-shot emitter has finished (i.e. all particles are dead) all particles mid-air vanish as the emitter restarts?
If so, then I oppose this idea: If the emitter isn't done, setting emitting = true
shouldn't do a reset (kill existing particles and restart), but more like a resume: leave live particles to reach the end of their lifespan while returning to "frame 0" of the emitter.
Tried my own way to fix it by forcing a particle restart when both emission and activity are false #https://github.com/godotengine/godot/issues/83909#issuecomment-1779657950. Which while great when testing particle effects in editor, It's understandable how re triggering oneshot in rapid sequence intentionally could lead to hiccups.
What makes this difficult to work with is that one shot is a property of the Particle Node, but not the Particle Resource. As far as I know, the Particle Resource has no awareness of what one shot even is, meaning that it's... well, clear why it's problematic in fixing.
I've read the concerns in this proposal and i feel like right now we're stuck in this conundrum because we're trying to shoehorn something that's logically different into a property. Please bear with me, I'll explain what i mean.
Properties of an object are meant to represent the state of an object. The pen is blue. The water is cold. Functions of an object are meant to invoke functionality of an object. The pen breaks. The water shoots out of a fountain.
If we consider the situation with particle, we're in a bit of a funny situation here: if a particle system was a hose with water inside, it being emitting or not would be a state of the emitter (hose). But suddenly, if we use oneshot, emitting is now a punctual thing that we need to trigger at a specific point in time. It's a function. Gunpowder in a gun doesn't make it shoot, someone has to pull a trigger to make it explode and shoot.
So the reason why particles aren't quite working for oneshot is because we're using the wrong tool for the job. One of the reasons why we're using the wrong tool for the job is also because the animation player cannot trigger functions in editor (for good reasons, but that doesn't make it any less problematic for us)
I think here we need to take a step back and consider how we'd solve this problem in the beginning, if particles didn't exist and we were designing them from scratch, and then try and see what we can do to fit this new approach in the existing one. If we can. And if we cannot, how to extend things in a non-compat breaking way.
I have been working on improving the documentation for the GPU particles, and the revised version adds a tip that the developer should use restart()
after receiving Finished signal from the one-shot emitter to reset the emission cycle.
https://github.com/godotengine/godot/pull/83622
The way "emitting" currently works is in my opinion how is should work. When the documentation is updated, I think how the emitter works is entirely intuitive.
The oneshot workflow remains a pain to work with and I agree with the people in the thread here that it needs improvements.
Hello there ! I just wanna say as well i'm having issue with that and that's so strange beceause Godot is such a smooth and fluid game Engine and when it comes to instanciates particules .. Yeargh
I'm just referecing the only way to workaround this without code i know
My problem with OneShot is not even restarting it, what I would like is to play the particle again without deleting the existing particles
for example, my raycast gun has a hit effect particle. I would like to move it to the hit particle to the inpact point and play it. if I try to do it again while the previous play is not finished I have to use restart() and that will erase the current effect and look jarring. so for now I am spawning a new particle every time I need the hit effect, but that's not very performant
@Dusk-Dawn do you mind opening a proposal about being able to restart particles and let existing ones continue to exist?
I can tell you already that due to godot's architecture it will probably be quite complex to achieve, but I do agree it's worth thinking about solutions for this.
The way I've seen this done is to have multiple hit effects, one for one shot hit effects (which you spawn on every hit) and one for continuous hit effects of which you control emissions and position
Describe the project you are working on
Godot Engine
Describe the problem or limitation you are having in your project
The behavior of the
emitting
property on one shot ParticleSystems is not very intuitive. Callingrestart
or settingemitting
for the first time do the same. When turningemitting
of after that the particle system will not emit anymore particles. But now when changingemitting
totrue
again it will be reset tofalse
without any effect. Usingemitting = true
again is only possible after the particle system would have finished ifemitting
was never set tofalse
. In addition this reseting takes some time for updating the inspector which makes it feel very bugged. This can confuse users about the stability of particle systems in general and does not help with solving any problems.Describe the feature / enhancement and how it helps to overcome the problem or limitation
I propose, that setting
emitting
totrue
will always triggerrestart
internaly ifone_shot == true
. The current behavior feels buggy and serves no real purpose so it should be changed to feel more usefull and reliable. The behavior for settingemitting
tofalse
will stay the same as it works and there might be use cases for that.As the current solution is more like undefined behavior this is not a breaking API change IMHO
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
I can implement that. The proposal is ment to get feedback on the idea.
If this enhancement will not be used often, can it be worked around with a few lines of script?
Nope
Is there a reason why this should be core and not an add-on in the asset library?
Can only be solved in core