Search Unity

Bug Inconsistent behavior on whether particle effects play or not.

Discussion in 'Scripting' started by cat_hill, Mar 18, 2023.

  1. cat_hill

    cat_hill

    Joined:
    Feb 23, 2023
    Posts:
    27
    I'm working on "Challenge 4" https://learn.unity.com/tutorial/challenge-4-soccer-scripting and struggling with the particle effects playing or not. It seems many other tutorial users are having the same problem and I haven't found any evidence of what can be causing this.

    I am holding the space key down. The relevant code is being triggered (shown by the debug log in screen below). Note that in Figure 1
    isplaying
    is true but that the "particles" mini window shows that it's not playing. The thing is that if I mess around with the space long enough, it eventually does play and then seems to play on demand. See figure 2. It's just that only sometimes holding down space doesn't do anything. And then it just randomly works. Or sometimes I start a new game and it works fine with no issue. My code is below the screenshots below.

    Best hypothesis - there is something weird going on with processing user input because whenever I tried to use my mouse to pause the play so that I could take a screenshot for this forum post the particle effect magically began playing. I had to use the hotkey "CTRL-SHIFT-P" so that I could take screenshots to show you. It's seemingly random because sometimes it works just fine on the first play attempt.

    Figure 1 : Effect not playing even though
    isPlaying 
    is
    true
    .
    upload_2023-3-18_11-41-51.png

    Figure 2: It plays moments later in the same session with no code changes or restart.
    upload_2023-3-18_11-42-13.png

    Code (CSharp):
    1. void Update()
    2.     {
    3.         // Add force to player in direction of the focal point (and camera)
    4.         float verticalInput = Input.GetAxis("Vertical");
    5.         bool turbo = Input.GetKey(KeyCode.Space);
    6.         int turboMultiplier;
    7.         if (turbo) {
    8.             turboMultiplier = 2;
    9.             turboParticleEffect.Play();
    10.             Debug.Log("Turbo Particle Effect Status:  "+turboParticleEffect.isPlaying);
    11.         } else {
    12.             turboMultiplier = 1;          
    13.         }
    14.         if (Input.GetKeyUp(KeyCode.Space)) {
    15.             turboParticleEffect.Stop();
    16.             Debug.Log("Turbo Particle Effect Status:  " + turboParticleEffect.isPlaying);
    17.         }
    18.  
    19.         playerRb.AddForce(focalPoint.transform.forward * verticalInput * speed * Time.deltaTime * turboMultiplier);
    20.  
    21.         // Set powerup indicator position to beneath player
    22.         powerupIndicator.transform.position = transform.position + new Vector3(0, -0.6f, 0);
    23.         turboParticleEffect.transform.position = transform.position + new Vector3(0, -0.6f, 0);
    24.  
    25.     }
     
  2. cat_hill

    cat_hill

    Joined:
    Feb 23, 2023
    Posts:
    27
    Interestingly ChatGPT had a great suggestion for me that seems to fix the problem above (I don't know why and would love to understand).. but gives me a different problem.

    The different problem is that once
    Stop()
    is called isPlaying continues to be true until the effect fully dissipates. That means future presses of the Space key have no effect for some cooldown period. But how would I get it to force Play() again in that case (without causing the issue from my original post).

    Log of chat GPT below
    ----

    Me: write me unity code to start and stop a particle effect based on holding down space key

    ChatGPT: Sure, here's an example code snippet in C# for Unity that starts and stops a particle effect when the space key is held down:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ParticleController : MonoBehaviour
    5. {
    6.    public ParticleSystem particleSystem;
    7.  
    8.    void Update()
    9.    {
    10.        if (Input.GetKey(KeyCode.Space))
    11.        {
    12.            if (!particleSystem.isPlaying)
    13.            {
    14.                particleSystem.Play();
    15.            }
    16.        }
    17.        else
    18.        {
    19.            if (particleSystem.isPlaying)
    20.            {
    21.                particleSystem.Stop();
    22.            }
    23.        }
    24.    }
    25. }
    In this code, we define a ParticleSystem variable called particleSystem that represents the particle effect we want to control. Then, in the Update method, we check if the space key is being held down using Input.GetKey(KeyCode.Space).

    If it is, we check if the particle effect is not already playing using !particleSystem.isPlaying. If it's not, we start the particle effect by calling the Play() method on the particleSystem variable.

    If the space key is not being held down, we check if the particle effect is already playing using particleSystem.isPlaying. If it is, we stop the particle effect by calling the Stop() method on the particleSystem variable.

    Note that this code assumes that the ParticleSystem component is attached to the same GameObject as the ParticleController script. If it's attached to a different GameObject, you'll need to update the code to reference it correctly.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    cat_hill likes this.
  4. cat_hill

    cat_hill

    Joined:
    Feb 23, 2023
    Posts:
    27
    Thanks Kurt. I also found this thread just now that seems to provide more evidence of the buggy behavior of Play/Stop and other folks suggesting to use Emit.
    https://answers.unity.com/questions/513517/particlesystemplay-does-not-play-particle.html

    Interestingly the suggested code in that thread also matches what ChatGPT suggested as a solution. It makes the behavior deterministic (which is great!) but now I'd trying to get a different behavior. This is what happens currently

    1. When
      Play() 
      is called, the effect works as expected
    2. Space is let go and new particles are no longer emitted but the existing particle effect keeps playing.
      isPlaying
      returns
      true
      .
    3. Play() 
      does nothing until the previously emitted particles complete their effect.
      isPlaying 
      stays
      true
      until completion of effect.
    4. After waiting, triggering
      Play() 
      now has desired effect.
    Here's what I'd like to have happen.
    1. When
      Play() 
      is called and the effect works as expected
    2. Space is let go and new particles are no longer emitted but the existing particle effect keeps playing.
      isPlaying
      returns
      true
      .
    3. Pressing space immediately after triggers
      Play() 
      which emits more particles. In parallel, the previously emitted particles continue to animate.
    Does this require two (or more)
    ParticleSystem 
    objects to allow for multiple effects to happen in parallel. I'm a little apprehensive about coding with
    Emit()
    and specifying particle counts.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Not sure I follow your questions above. You never call Play() with my technique. Read again carefully how it gets set to play.

    Again, I just don't follow you. What part (as in, show me in the API documentation) is making you apprehensive?
     
  6. cat_hill

    cat_hill

    Joined:
    Feb 23, 2023
    Posts:
    27
    Reading this https://docs.unity3d.com/ScriptReference/ParticleSystem.Emit.html gave me the impression a lot of trial and error is involved with using Emit() to re-create what Play() does.

    I understand that to create the effects I want, Emit() is probably necessary and appreciate you pointing me in that direction.

    I have it working "good enough" for now with Play() and will relook at Emit() when I want to do some more advanced effects.