TowerDefenseGame/Assets/Scripts/Runtime/Environment/VfxHandler.cs
Nico a52bbb0849 Create object pooling system
Optimize VFX and builder handling mechanics
2025-06-28 11:00:01 -07:00

78 lines
2.6 KiB
C#

using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Pool;
public class VfxHandlerBase {
private List<ObjectPool<ParticleSystem>> ParticleSystemPool = new List<ObjectPool<ParticleSystem>>();
private GameObject PoolParentContainer;
public VfxHandlerBase(GameObject vfx, int defaultCap = 10, int maxCap = 50) {
if (!vfx) { Debug.LogError($"You did not pass vfx...."); }
PoolParentContainer = new GameObject($"{vfx.name} Pool");
var particleSystems = vfx.GetComponentsInChildren<ParticleSystem>();
particleSystems.ToListPooled().ForEach(x => GenerateVfxPool(x, defaultCap, maxCap));
}
public void PlayAll(Vector3? position = null, Quaternion? rotation = null) {
if (position == null) position = Vector3.zero;
if (rotation == null) rotation = Quaternion.Euler(0, 0, 0);
Get((Vector3)position, (Quaternion)rotation);
//var particleSystems = obj.GetComponentsInChildren<ParticleSystem>();
//particleSystems.ToListPooled().ForEach((x) => x.Play());
}
public List<ParticleSystem> Get(Vector3 position, Quaternion rotation) {
var particleSystems = ParticleSystemPool.ToList().Select(x => x.Get()).ToList();
particleSystems.ForEach(x => {
x.transform.SetPositionAndRotation(position, rotation);
x.Play();
});
return particleSystems;
}
private void GenerateVfxPool(ParticleSystem vfx, int defaultCap = 10, int maxCap = 50) {
if (!vfx) { Debug.LogError($"You did not pass vfx...."); }
ObjectPool<ParticleSystem> pool = null;
pool = new ObjectPool<ParticleSystem>(
createFunc: () => {
var inst = Object.Instantiate(vfx, PoolParentContainer.transform);
inst.gameObject.SetActive(false);
var main = inst.main;
main.loop = false;
main.stopAction = ParticleSystemStopAction.Callback;
inst.gameObject.AddComponent<ReturnToPool>().Initialize(pool);
return inst;
},
actionOnGet: ps => ps.gameObject.SetActive(true),
actionOnRelease: ps => {
ps.Clear();
ps.gameObject.SetActive(false);
},
//actionOnDestroy: ps => Object.Destroy(ps.gameObject),
collectionCheck: true,
defaultCapacity: defaultCap,
maxSize: maxCap
);
ParticleSystemPool.Add(pool);
}
public class ReturnToPool : MonoBehaviour {
private ObjectPool<ParticleSystem> pool;
public void Initialize(ObjectPool<ParticleSystem> pool) {
this.pool = pool;
}
private void OnParticleSystemStopped() {
pool.Release(GetComponent<ParticleSystem>());
}
}
}