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?
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.