/// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Samples { using System.Collections; using Unity.Collections; using Unity.Entities; using Unity.Mathematics; using UnityEngine; using UnityEngine.Pool; using UnityEngine.UI; /// /// Adds effects to the entities sample scene. /// public class EffectsManager : MonoBehaviour { [Tooltip("The explosion prefab.")] [SerializeField] protected GameObject m_Explosion; [Tooltip("A reference to the turret's healthbar.")] [SerializeField] protected Slider m_TurretHealthbar; private ObjectPool m_ExplosionPool; private EntityCommandBuffer m_EntityCommandBuffer; /// /// Initializes the default values. /// private void Awake() { m_ExplosionPool = new ObjectPool(() => // Create. { var explosion = GameObject.Instantiate(m_Explosion); explosion.GetComponent().Pool = m_ExplosionPool; return explosion; }, (GameObject explosion) => // Take. { explosion.SetActive(true); }, (GameObject explosion) => // Return. { explosion.SetActive(false); }, (GameObject explosion) => // Destroy. { DestroyImmediate(explosion); }); } /// /// The entity subscene has loaded. /// private void Start() { StartCoroutine(RegisterEvents()); } /// /// Subscribes to the interested events. /// private IEnumerator RegisterEvents() { DamageTaskSystem damageTaskSystem; do { damageTaskSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged(); yield return new WaitForEndOfFrame(); // The systems aren't available immediately. } while (damageTaskSystem == null); damageTaskSystem.OnDamage += OnDamageTurret; var destroyTaskSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); destroyTaskSystem.OnDestroyEntity += OnDestroyEntity; // Add the necessary systems that are not created by Behavior Designer. var systemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); systemGroup.AddSystemToUpdateList(destroyTaskSystem); systemGroup.AddSystemToUpdateList(World.DefaultGameObjectInjectionWorld.GetOrCreateSystem()); } /// /// The entity has been destroyed. /// /// The position of the entity. private void OnDestroyEntity(float3 position) { var explosion = m_ExplosionPool.Get(); explosion.transform.position = position; } /// /// The turret has been damaged. /// /// The remaining health amount. private void OnDamageTurret(float healthAmount) { healthAmount = Mathf.Clamp(healthAmount, 0, Mathf.Abs(healthAmount)); m_TurretHealthbar.value = healthAmount; // Destroy the turret when it doesn't have any more health. if (healthAmount == 0) { var explosion = m_ExplosionPool.Get(); explosion.transform.position = Vector3.zero; explosion.transform.localScale = new Vector3(4, 4, 4); // The turret base should also be destroyed. var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; var query = new EntityQueryBuilder(Allocator.Temp).WithAll().Build(entityManager); var entities = query.ToEntityArray(AllocatorManager.Temp); // Only one entity will be returned. m_EntityCommandBuffer = new EntityCommandBuffer(Allocator.Persistent); if (entities.Length > 0) { m_EntityCommandBuffer.DestroyEntity(entities[0]); } query.Dispose(); entities.Dispose(); // .. As well as the turret weapon. query = new EntityQueryBuilder(Allocator.Temp).WithAll().WithOptions(EntityQueryOptions.IgnoreComponentEnabledState).Build(entityManager); entities = query.ToEntityArray(AllocatorManager.Temp); // Only one entity will be returned. if (entities.Length > 0) { m_EntityCommandBuffer.DestroyEntity(entities[0]); } query.Dispose(); entities.Dispose(); // All of the currently charging agents should be destroyed. query = new EntityQueryBuilder(Allocator.Temp).WithAll().Build(entityManager); entities = query.ToEntityArray(AllocatorManager.Temp); for (int i = 0; i < entities.Length; ++i) { m_EntityCommandBuffer.DestroyEntity(entities[i]); } query.Dispose(); entities.Dispose(); enabled = true; } } /// /// Runs the EntityCommandBuffer if it exists. /// private void Update() { if (m_EntityCommandBuffer.IsEmpty) { enabled = false; return; } m_EntityCommandBuffer.Playback(World.DefaultGameObjectInjectionWorld.EntityManager); m_EntityCommandBuffer.Dispose(); } /// /// The component has been destroyed. /// private void OnDestroy() { if (World.DefaultGameObjectInjectionWorld == null) { return; } var destroySystem = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged(); if (destroySystem != null) { destroySystem.OnDestroyEntity -= OnDestroyEntity; } var damageSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged(); if (damageSystem != null) { damageSystem.OnDamage -= OnDamageTurret; } } } }