Reputation: 151
I'm trying to change my particle system function to a pooling instead of instantiating everytime. I want to reuse the particles. How is that possible? I have no idea how to start although i watched the unity tutorial but somehow it's still unclear. maybe because im calling the particle system function in other classes it's confusing me somehow.
public ParticleSystem[] Myeffects;
public void Particle(int particleNum, Vector3 Pos)
{
if (Myeffects != null && Myeffects[particleNumber] != null )
{
if (Myeffects[particleNumber].isPlaying)
Myeffects[particleNumber].Stop();
ParticleSystem temp = Instantiate(Myeffects[particleNum], particlePos, new Quaternion()) as ParticleSystem;
temp.Play();
}
}
}
Upvotes: 3
Views: 6167
Reputation: 125315
First of all, Select your Particle System prefab/TNT then make sure that Play On Awake is unchecked. The pooling script below is dedicated tricky way to accomplish that. It will create an array of ParticleSystem
specified then re-use them. Notice that ParticlePool
does not inherit from MonoBehaviour
, so make sure to copy it directly.
using UnityEngine;
using System.Collections;
using System;
public class ParticlePool
{
int particleAmount;
ParticleSystem[] NormalParticle;
ParticleSystem[] TNTParticle;
public ParticlePool(ParticleSystem normalPartPrefab, ParticleSystem tntPartPrefab, int amount = 10)
{
particleAmount = amount;
NormalParticle = new ParticleSystem[particleAmount];
TNTParticle = new ParticleSystem[particleAmount];
for (int i = 0; i < particleAmount; i++)
{
//Instantiate 10 NormalParticle
NormalParticle[i] = GameObject.Instantiate(normalPartPrefab, new Vector3(0, 0, 0), new Quaternion()) as ParticleSystem;
//Instantiate 10 TNTParticle
TNTParticle[i] = GameObject.Instantiate(tntPartPrefab, new Vector3(0, 0, 0), new Quaternion()) as ParticleSystem;
}
}
//Returns available GameObject
public ParticleSystem getAvailabeParticle(int particleType)
{
ParticleSystem firstObject = null;
//Normal crate
if (particleType == 0)
{
//Get the first GameObject
firstObject = NormalParticle[0];
//Move everything Up by one
shiftUp(0);
}
//TNT crate
else if (particleType == 1)
{
//Get the first GameObject
firstObject = TNTParticle[0];
//Move everything Up by one
shiftUp(1);
}
return firstObject;
}
//Returns How much GameObject in the Array
public int getAmount()
{
return particleAmount;
}
//Moves the GameObject Up by 1 and moves the first one to the last one
private void shiftUp(int particleType)
{
//Get first GameObject
ParticleSystem firstObject;
//Normal crate
if (particleType == 0)
{
firstObject = NormalParticle[0];
//Shift the GameObjects Up by 1
Array.Copy(NormalParticle, 1, NormalParticle, 0, NormalParticle.Length - 1);
//(First one is left out)Now Put first GameObject to the Last one
NormalParticle[NormalParticle.Length - 1] = firstObject;
}
//TNT crate
else if (particleType == 1)
{
firstObject = TNTParticle[0];
//Shift the GameObjects Up by 1
Array.Copy(TNTParticle, 1, TNTParticle, 0, TNTParticle.Length - 1);
//(First one is left out)Now Put first GameObject to the Last one
TNTParticle[TNTParticle.Length - 1] = firstObject;
}
}
}
Then, your ParticleHolder
script should be updated with the code below. That's it. No more instantiation.
public class ParticleHolder : MonoBehaviour
{
public ParticleSystem[] effects;
ParticlePool particlePool;
void Start()
{
// 0 = Normal crate
// 1 = TNT crate
particlePool = new ParticlePool(effects[0], effects[1], 5);
}
public void playParticle(int particleType, Vector3 particlePos)
{
ParticleSystem particleToPlay = particlePool.getAvailabeParticle(particleType);
if (particleToPlay != null)
{
if (particleToPlay.isPlaying)
particleToPlay.Stop();
particleToPlay.transform.position = particlePos;
particleToPlay.Play();
}
}
}
Upvotes: 3