Particles destroyed even before I play it

I used some particles from the unity asset store for a cooler effect.
I followed every step:

  • open my player prefab
  • dragged the prefab particle from my assets onto the player prefab
  • assigned the particle from the prefab hierarchy (and not from the assets) onto the playerController script
  • unchecked the “play on awake” both from the particle inside the prefab, and also from the player in the main hierarchy

But yet, when I play my game, and when I call the particles.Play() upon tapping space, I get the:

the object of type particlesystem has been destroyed

so obviously nothing work
here is my code, very simple

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField] float moveSpeed = 2f;
    [SerializeField] ParticleSystem jumpEffect;
    void Start()
    {
        Debug.Log("Hello world");
    }

    // Update is called once per frame
    void Update()
    {
        MovePlayer();
    }

    void MovePlayer()
    {
        float x = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
        float z = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
        transform.Translate(x, 0, z);

        if (Input.GetKeyDown("space"))
        {
            Debug.Log("space key was pressed");
            if (jumpEffect != null)
            {
                jumpEffect.Play();
            } else
            {
                Debug.Log("jump particle was destroyed");
            }
        }
    }
}

Does the particles play once? Check the particle system. There’s a ‘Stop Action’ field. Make sure it is set to ‘None’

Thanks for your reply @bixarrio
I checked and I confirm it was already set to None.

However, when I “play” my game, I also see the final flash of the particle, as if it had played right before the play, although again the play on awake is not checked

And even if it plays once, nowhere do I destroy the particle in my code so I dont know why I get this error

How often does this piece of code get executed while the game is running?

if (jumpEffect != null)
{
  jumpEffect.Play();
}

Since the code does not check whether the particle system is already playing, it might be that the Play() method restarts the particle system each frame. At least, it would explain why you see a flash of the particle. That’s just a guess, though.

It only plays when the space key is pressed

Ah, you are right. I mixed up GetKey with GetKeyDown.

1 Like

but the problem is that even if I remove that piece of code, the particle will still play upon “Playing” my game; then destroy itself.

So I come with more information from the developer of this particle asset
(for reference, it’s the Cartoon FX Remaster)

Here is what he mentioned about these particles:

Almost all Cartoon FX prefabs have a “CFXR_Effect” script that handles various things (dynamic lights, screen shake, etc.) and also the lifecycle of these prefabs. Most of the time, it is set to “Destroy,” which will destroy the prefab as soon as the script detects that there are no more emitted particles.

This allows for an easy workflow where the prefab is instantiated, and then you don’t have to worry about it anymore.

To disable this, by selecting the source prefab, it’s done here:
image

I believe the issue is coming from there.

So I tried to put the stop action to “none” instead of destroy, yet it still plays right away when I launch my game, and it seems to destroy itself right away.

Perhaps this is not the correct way to actually use particles?
Shouldn’t I instanciate it and let it be destroyed automatically everytime I need it?

OK, So I downloaded the free version and tested it. On the particle system, you just need to uncheck Play on Awake and on the CFXR_Effect script, you need to change Clear Behaviour to None.

Edit
I just noticed that mine is also playing on start, even with Play on Awake switched off. Gimme a minute.

Edit
OK, So it’s not the particle system. The CFXR_Effect script that works in conjunction with the particle system doesn’t know that Play on Awake is unchecked so it’s doing animated lights and screenshake when the prefab is Awake. Just doing particleSystem.Play() on these will lose the effect that comes with that component because the component has already played. The best would be to instantiate the prefab instead of playing the particle system, and then letting it destroy itself when it’s done.

1 Like

Thank you so much for taking the time to look into it!

I confirmed it worked this way.
(although oddly enough, I still see a weird flashing point when I launch my game below my player, so for some reason it seems to be played at least once without me triggering it)
=> Ok thank you for finding a solution to that one as well in your edit! :slight_smile:

But now it leaves me with a question:
Should I uncheck play on awake from the effect inside the player prefav?
Or should I uncheck it from my hierarchy under my player?
Or should I uncheck it from both?

also, I saw in the tutorial I gotta drag the particle from the prefab hierarchy onto the parent who holds the collision script;
but then when I leave the player prefab, in the hierarchy that player doesn’t have the particle attached to its script; should I do it there as well?
Or does it activate it for the parent too when I made it in the prefab?
(which could lead to confusion and me thinking I didnt drag the particle if I check the player in a few month and see “none” under that particle in the script inspector)

I am also wondering if this is actually good practice to have a particle not destroy itself after playing?
Isn’t it bad for performance?
Or perhaps it’s better to not destroy it if I intend to re-use it often?

Edit:

Okay so I gotta learn how to instantiate a prefab.
But then, this is completely unrelated to this tutorial?
Like I no longer have to drag the prefab particle into my prefab player etc?
I just gotta instantiate it and it will play?
But then, how does it position itself exactly where I want it to?
(or perhaps this is part of the instantiate, I am very new to unity)

It’s not in the hierarchy because the instance in the hierarchy has now changed. You should see a blue line next to the field. You can right-click on it and select Revert. It should then put the object back as it is in the prefab.

It is a little bad on the performance, but these effects you’re using was made to be instantiated. The attached script CFXR_Effect assumes that the particles will be created and does the screenshake and lights thing I mentioned earlier as soon as it’s created. There doesn’t seem to be a way to execute it later. So, for these effects you’re going to have to instantiate them when you need them.

It’s not hard to instantiate the object. You will change your code a little

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField] float moveSpeed = 2f;
    [SerializeField] GameObject jumpEffect; // <-- Change this to GameObject
    void Start()
    {
        Debug.Log("Hello world");
    }

    // Update is called once per frame
    void Update()
    {
        MovePlayer();
    }

    void MovePlayer()
    {
        float x = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
        float z = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
        transform.Translate(x, 0, z);

        if (Input.GetKeyDown("space"))
        {
            Debug.Log("space key was pressed");
            // We instantiate the particles here
            Instantiate(jumpEffect, transform.position, Quaternion.identity);
        }
    }
}

Above, I have changed the type from ParticleSystem to GameObject. You will remove the prefab from your player prefab and drag the effect prefab from the project folder into this field.
Then, when you press the ‘space’ key, we instantiate the effect. It is being instantiated where the player is currently at with no rotation.

1 Like

Thank you so much for all of this, I really appreciate it! :slight_smile:

Edit:
Okay, a few more questions (sorry):

  • I added the prefab particle into the player prefab as you mentioned

    But then I got the error :
UnassignedReferenceException: The variable jumpEffect of PlayerController has not been assigned.
You probably need to assign the jumpEffect variable of the PlayerController script in the inspector.

And now it “half works”
=>
image

I only get the flashy point below my player, without the “bang” effect that I should have (like below)
image

So I guess instantiating it does not bring all the children effect the particle should have, confusing

Does this thread have got the right tag? This does not look like the Project Boost project.

it started off the project boost, under the particle lesson.
I just wanted to use my own particles from unity asset store, then perhaps it went out of scope indeed since the particles I used behave differently.

If you still get the UnassignedReferenceException error but your code is working at runtime, that’s probably just a ‘false’ warning. You could try to initialise the jumpEffect variable with default at the top of your code.

If an instantiated particle system does not emit any particles, ‘Play On Awake’ either wasn’t enabled in the prefab, or, if it is not supposed to be enabled, your code does not call Play on the instantiated ParticleSystem object.

ParticleSystem objects can emit particles only if the game object (and its parents) are enabled.

If nothing worked and if you cannot find any solution, write a little test script that instantiates the particle system in your scene and calls Play on it. That’s often better than trying to analyse the problem in another complex context. From what I see, your player has got dozens of children, which are either enabled or disabled, and who knows what else happens to your player which might affect the particle system. From what I understood, you currently don’t know either if your particle system works as expected, so this is the first thing you should check.

1 Like

Thank you for these additional information;

It is now all working thanks to all the help provided above.

I now instantiate the particle prefab and let the script handle the destroy and everything works as expected.
It was indeed a different use case from the original tutorial which only needed to Play(), my bad for using external assets :slight_smile:

Good job! :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms