using ActionGameFramework.Projectiles; using Core.Utilities; using TowerDefense.Towers; using UnityEngine; namespace TowerDefense.Effects { /// /// Class for spawning and managing effects on this projectile. Used for effects that should persist /// a little longer after a projectile is destroyed/repooled. Creates the effect on enable, moves it to /// follow us every frame while we're active. /// /// On disable, it'll try and find a SelfDestroyTimer on the effect to trigger its destruction, otherwise /// repools it immediately. /// [RequireComponent(typeof(IProjectile))] public class ProjectileEffect : MonoBehaviour { /// /// Preafb that gets spawned when this projectile fires /// public GameObject effectPrefab; /// /// Transform the effect follows /// public Transform followTransform; /// /// Cached spawned effect /// GameObject m_SpawnedEffect; /// /// Cached destruction timer on the spawned object /// SelfDestroyTimer m_DestroyTimer; /// /// Cached poolable effect on the spawned object /// PoolableEffect m_Resetter; /// /// Cached projectile /// IProjectile m_Projectile; /// /// Register projectile fire events /// protected virtual void Awake() { m_Projectile = GetComponent(); m_Projectile.fired += OnFired; if (followTransform != null) { followTransform = transform; } } /// /// Unregister delegates /// protected virtual void OnDestroy() { m_Projectile.fired -= OnFired; } /// /// Spawn our effect /// protected virtual void OnFired() { if (effectPrefab != null) { m_SpawnedEffect = Poolable.TryGetPoolable(effectPrefab); m_SpawnedEffect.transform.parent = null; m_SpawnedEffect.transform.position = followTransform.position; m_SpawnedEffect.transform.rotation = followTransform.rotation; // Make sure to disable timer if it's on initially, so it doesn't destroy this object m_DestroyTimer = m_SpawnedEffect.GetComponent(); if (m_DestroyTimer != null) { m_DestroyTimer.enabled = false; } m_Resetter = m_SpawnedEffect.GetComponent(); if (m_Resetter != null) { m_Resetter.TurnOnAllSystems(); } } } /// /// Make effect follow us /// protected virtual void Update() { // Make the effect follow our position. // We don't reparent it because it should not be disabled when we are if (m_SpawnedEffect != null) { m_SpawnedEffect.transform.position = followTransform.position; } } /// /// Destroy and start destruction of effect /// protected virtual void OnDisable() { if (m_SpawnedEffect == null) { return; } // Initiate destruction timer if (m_DestroyTimer != null) { m_DestroyTimer.enabled = true; if (m_Resetter != null) { m_Resetter.StopAll(); } } else { // Repool immediately Poolable.TryPool(m_SpawnedEffect); } m_SpawnedEffect = null; m_DestroyTimer = null; } } }