最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

c# - Newly spawned particles instantly destroyed after lifespan expires in a custom particle system script - Stack Overflow

matteradmin7PV0评论

I'm trying to create a particle system script from scratch. The problem is that I want to spawn particles and after a certain lifespan destroy them so it won't keep loading the memory with particles infinitly.

This is the Particle script. I set

using System.Collections.Generic;
using UnityEngine;

public class Particle : MonoBehaviour
{
    public Vector3 position;
    public Vector3 velocity;
    public Vector3 gravityAcceleration = new Vector3(0, -9.81f, 0);
    public float lifespan = 5f;

    void Start()
    {
        velocity = new Vector3(Random.Range(-2f, 2f), Random.Range(-2f, 2f), Random.Range(-2f, 2f));
    }

    // Update is called once per frame
    void Update()
    {
        // Update position and velocity
        velocity += gravityAcceleration*Time.deltaTime;
        transform.position += velocity*Time.deltaTime;

        // Decrease the lifespan of the particle
        lifespan -= Time.deltaTime;
        if (lifespan <= 0f && this.gameObject != null) 
        {
            Destroy(this.gameObject); // Destroy particle when lifespan expires
        }
    } 
}

and this is the emitter script:

using System.Collections.Generic;
using UnityEngine;

public class ParticleEmitter : MonoBehaviour {

    public GameObject particlePrefab; // This creates a reusable GameObsejt asset (prefab) to create and asign particles dynamically while the script runs.
    public float particleRate = 20f; // Particles created per second.
    public float timer = 0f; // Time interval between 2 particle creation cycles.
    //private List<GameObject> particles = new List<GameObject>(); // A list to store all the particles created so I can iterate and update/remove them.


    void CreateParticle() {
        GameObject particle = Instantiate(particlePrefab, transform.position, transform.rotation);
        //particles.Add(particle);
    }

    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;
        
        if(timer >= 1f / particleRate) {
            CreateParticle();   
            timer = 0f;
        }

    }
}

In this example I have set the lifespan at 2 seconds and as you can see after 2 seconds all particles are destroyed, and after that all newly spawned particles are also destroyed instantly. It appears that this lifespan variable is shared between all particles, how can I make it unique for each particle?

example lifespan = 2 sec.

I'm trying to create a particle system script from scratch. The problem is that I want to spawn particles and after a certain lifespan destroy them so it won't keep loading the memory with particles infinitly.

This is the Particle script. I set

using System.Collections.Generic;
using UnityEngine;

public class Particle : MonoBehaviour
{
    public Vector3 position;
    public Vector3 velocity;
    public Vector3 gravityAcceleration = new Vector3(0, -9.81f, 0);
    public float lifespan = 5f;

    void Start()
    {
        velocity = new Vector3(Random.Range(-2f, 2f), Random.Range(-2f, 2f), Random.Range(-2f, 2f));
    }

    // Update is called once per frame
    void Update()
    {
        // Update position and velocity
        velocity += gravityAcceleration*Time.deltaTime;
        transform.position += velocity*Time.deltaTime;

        // Decrease the lifespan of the particle
        lifespan -= Time.deltaTime;
        if (lifespan <= 0f && this.gameObject != null) 
        {
            Destroy(this.gameObject); // Destroy particle when lifespan expires
        }
    } 
}

and this is the emitter script:

using System.Collections.Generic;
using UnityEngine;

public class ParticleEmitter : MonoBehaviour {

    public GameObject particlePrefab; // This creates a reusable GameObsejt asset (prefab) to create and asign particles dynamically while the script runs.
    public float particleRate = 20f; // Particles created per second.
    public float timer = 0f; // Time interval between 2 particle creation cycles.
    //private List<GameObject> particles = new List<GameObject>(); // A list to store all the particles created so I can iterate and update/remove them.


    void CreateParticle() {
        GameObject particle = Instantiate(particlePrefab, transform.position, transform.rotation);
        //particles.Add(particle);
    }

    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;
        
        if(timer >= 1f / particleRate) {
            CreateParticle();   
            timer = 0f;
        }

    }
}

In this example I have set the lifespan at 2 seconds and as you can see after 2 seconds all particles are destroyed, and after that all newly spawned particles are also destroyed instantly. It appears that this lifespan variable is shared between all particles, how can I make it unique for each particle?

example lifespan = 2 sec.

Share Improve this question edited Nov 20, 2024 at 11:34 DarkBee 15.5k8 gold badges72 silver badges118 bronze badges asked Nov 18, 2024 at 13:29 Thanasis MpoulionisThanasis Mpoulionis 234 bronze badges 11
  • 1 What is the error you get in the console? – Kibsgaard Commented Nov 18, 2024 at 13:40
  • It sounds like you need to set the particle emitter lifespan, not just kill the emitter# – BugFinder Commented Nov 18, 2024 at 13:54
  • Btw would be way easier to just use the delay parameter of Destroy(object, delay); .. also in general you might want to look into object pooling for this instead of instantiate and destroy a lot of objects – derHugo Commented Nov 18, 2024 at 13:58
  • true but rather than remaking the emitter each time, why not just limit the lifespan of the actual emitted particles – BugFinder Commented Nov 18, 2024 at 14:00
  • Do you by accident also have a particle component on the emitter? – derHugo Commented Nov 18, 2024 at 14:04
 |  Show 6 more comments

1 Answer 1

Reset to default 0

Example:

Use coroutine to disable/destroy the Particle's gameObject after lifespan.

Remove from Update:

        lifespan -= Time.deltaTime;
        if (lifespan <= 0f && this.gameObject != null) 
        {
            Destroy(this.gameObject); // Destroy particle when lifespan expires
        }
    void Start()
    {
        velocity = new Vector3(Random.Range(-2f, 2f), Random.Range(-2f, 2f), Random.Range(-2f, 2f));
        StartCoroutine(LifespanRoutine());
    }

    private IEnumerator LifespanRoutine() 
    {
         yield return new WaitForSeconds(lifespan);
         Destroy(gameObject);
    }

P. S.
A better approach is to set up object pooling instead of instantiating. Why even use a custom particle system? MonoBehaviour is quite a large wrapper for particles.

Articles related to this article

Post a comment

comment list (0)

  1. No comments so far