Files
2026-05-10 11:47:55 -04:00

164 lines
5.7 KiB
C#

#if GRAPH_DESIGNER
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Runtime.Tasks.Actions.ParticlesTasks
{
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions.GameObjectTasks;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
[Opsive.Shared.Utility.Category("Particles")]
[Opsive.Shared.Utility.Description("Manages particle system pooling with automatic cleanup.")]
public class Pool : Action
{
[Tooltip("The parent GameObject to create pooled particle systems under.")]
[SerializeField] protected SharedVariable<GameObject> m_PoolParent;
[Tooltip("The ParticleSystem prefab to pool.")]
[SerializeField] protected SharedVariable<GameObject> m_ParticleSystemPrefab;
[Tooltip("The initial pool size.")]
[SerializeField] protected SharedVariable<int> m_PoolSize = 5;
[Tooltip("The maximum pool size.")]
[SerializeField] protected SharedVariable<int> m_MaxPoolSize = 10;
[Tooltip("The currently active ParticleSystem from the pool.")]
[SerializeField] [RequireShared] protected SharedVariable<ParticleSystem> m_ActiveParticleSystem;
private ObjectPool<GameObject> m_Pool;
private List<ParticleSystem> m_ActiveSystems = new List<ParticleSystem>();
/// <summary>
/// Called when the state machine starts.
/// </summary>
public override void OnAwake()
{
base.OnAwake();
if (m_ParticleSystemPrefab.Value != null) {
InitializePool();
}
}
/// <summary>
/// Initializes the particle system pool.
/// </summary>
private void InitializePool()
{
if (m_Pool != null) {
return;
}
var poolParent = m_PoolParent.Value != null ? m_PoolParent.Value : m_GameObject;
m_Pool = new ObjectPool<GameObject>(
createFunc: () => {
var go = Object.Instantiate(m_ParticleSystemPrefab.Value);
go.transform.SetParent(poolParent != null ? poolParent.transform : null);
go.SetActive(false);
return go;
},
actionOnGet: (obj) => {
obj.SetActive(true);
},
actionOnRelease: (obj) => {
obj.SetActive(false);
var particleSystem = obj.GetComponent<ParticleSystem>();
if (particleSystem != null) {
particleSystem.Stop();
particleSystem.Clear();
}
PoolManager.Instance.Unregister(obj);
},
actionOnDestroy: (obj) => {
Object.Destroy(obj);
},
collectionCheck: true,
defaultCapacity: m_PoolSize.Value,
maxSize: m_MaxPoolSize.Value
);
}
/// <summary>
/// Gets an available particle system from the pool.
/// </summary>
private ParticleSystem GetPooledParticleSystem()
{
if (m_Pool == null) {
return null;
}
var go = m_Pool.Get();
if (go != null) {
PoolManager.Instance.Register(go, m_Pool);
return go.GetComponent<ParticleSystem>();
}
return null;
}
/// <summary>
/// Updates the particle system pool.
/// </summary>
/// <returns>The status of the action.</returns>
public override TaskStatus OnUpdate()
{
for (int i = m_ActiveSystems.Count - 1; i >= 0; i--) {
if (m_ActiveSystems[i] == null || !m_ActiveSystems[i].isPlaying) {
if (m_ActiveSystems[i] != null && m_Pool != null) {
m_Pool.Release(m_ActiveSystems[i].gameObject);
}
m_ActiveSystems.RemoveAt(i);
}
}
if (m_ActiveParticleSystem.Value != null && !m_ActiveParticleSystem.Value.isPlaying) {
m_ActiveParticleSystem.Value = null;
}
return TaskStatus.Success;
}
/// <summary>
/// Plays a particle system from the pool.
/// </summary>
public void PlayFromPool(Vector3 position)
{
var particleSystem = GetPooledParticleSystem();
if (particleSystem != null) {
particleSystem.transform.position = position;
particleSystem.Play();
m_ActiveSystems.Add(particleSystem);
m_ActiveParticleSystem.Value = particleSystem;
}
}
/// <summary>
/// Called when the state machine is destroyed.
/// </summary>
public override void OnDestroy()
{
base.OnDestroy();
// Clean up pool when state machine is destroyed.
if (m_Pool != null) {
m_Pool.Dispose();
m_Pool = null;
}
}
/// <summary>
/// Resets the action values back to their default.
/// </summary>
public override void Reset()
{
base.Reset();
m_PoolParent = null;
m_ParticleSystemPrefab = null;
m_PoolSize = 5;
m_MaxPoolSize = 10;
m_ActiveParticleSystem = null;
}
}
}
#endif