wangguan
2020-12-29 452c75675679c44cc39b04bdb7d330d7c5c14d5c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using ActionGameFramework.Projectiles;
using Core.Utilities;
using TowerDefense.Towers;
using UnityEngine;
 
namespace TowerDefense.Effects
{
    /// <summary>
    /// 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.
    /// </summary>
    [RequireComponent(typeof(IProjectile))]
    public class ProjectileEffect : MonoBehaviour
    {
        /// <summary>
        /// Preafb that gets spawned when this projectile fires
        /// </summary>
        public GameObject effectPrefab;
 
        /// <summary>
        /// Transform the effect follows
        /// </summary>
        public Transform followTransform;
 
        /// <summary>
        /// Cached spawned effect
        /// </summary>
        GameObject m_SpawnedEffect;
        
        /// <summary>
        /// Cached destruction timer on the spawned object
        /// </summary>
        SelfDestroyTimer m_DestroyTimer;
 
        /// <summary>
        /// Cached poolable effect on the spawned object
        /// </summary>
        PoolableEffect m_Resetter;
 
        /// <summary>
        /// Cached projectile
        /// </summary>
        IProjectile m_Projectile;
 
        /// <summary>
        /// Register projectile fire events
        /// </summary>
        protected virtual void Awake()
        {
            m_Projectile = GetComponent<IProjectile>();
            m_Projectile.fired += OnFired;
            if (followTransform != null)
            {
                followTransform = transform;
            }
        }
 
        /// <summary>
        /// Unregister delegates
        /// </summary>
        protected virtual void OnDestroy()
        {
            m_Projectile.fired -= OnFired;
        }
 
        /// <summary>
        /// Spawn our effect
        /// </summary>
        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<SelfDestroyTimer>();
                if (m_DestroyTimer != null)
                {
                    m_DestroyTimer.enabled = false;
                }
                m_Resetter = m_SpawnedEffect.GetComponent<PoolableEffect>();
                if (m_Resetter != null)
                {
                    m_Resetter.TurnOnAllSystems();
                }
            }
        }
 
        /// <summary>
        /// Make effect follow us
        /// </summary>
        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;
            }
        }
 
        /// <summary>
        /// Destroy and start destruction of effect
        /// </summary>
        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;
        }
    }
}