1 using UnityEngine;
2 using System.Collections;
3
4 /*
5 DetonatorBurstEmitter is an interface for DetonatorComponents to use to create particles
6
7 - Handles common tasks for Detonator... almost every DetonatorComponent uses this for particles
8 - Builds the gameobject with emitter, animator, renderer
9 - Everything incoming is automatically scaled by size, timeScale, color
10 - Enable oneShot functionality
11
12 You probably don't want to use this directly... though you certainly can.
13 */
14
15 public class DetonatorBurstEmitter : DetonatorComponent
16 {
17 private ParticleEmitter _particleEmitter;
18 private ParticleRenderer _particleRenderer;
19 private ParticleAnimator _particleAnimator;
20
21 private float _baseDamping = 0.1300004f;
22 private float _baseSize = 1f;
23 private Color _baseColor = Color.white;
24
25 public float damping = 1f;
26 public float startRadius = 1f;
27 public float maxScreenSize = 2f;
28 public bool explodeOnAwake = false;
29 public bool oneShot = true;
30 public float sizeVariation = 0f;
31 public float particleSize = 1f;
32 public float count = 1;
33 public float sizeGrow = 20f;
34 public bool exponentialGrowth = true;
35 public float durationVariation = 0f;
36 public bool useWorldSpace = true;
37 public float upwardsBias = 0f;
38 public float angularVelocity = 20f;
39 public bool randomRotation = true;
40
41 public ParticleRenderMode renderMode;
42
43 //TODO make this based on some var
44 /*
45 _sparksRenderer.particleRenderMode = ParticleRenderMode.Stretch;
46 _sparksRenderer.lengthScale = 0f;
47 _sparksRenderer.velocityScale = 0.7f;
48 */
49
50 public bool useExplicitColorAnimation = false;
51 public Color[] colorAnimation = new Color[5];
52
53 private bool _delayedExplosionStarted = false;
54 private float _explodeDelay;
55
56 public Material material;
57
58 //unused
59 override public void Init()
60 {
61 print ("UNUSED");
62 }
63
64 public void Awake()
65 {
66 _particleEmitter = (gameObject.AddComponent<EllipsoidParticleEmitter>()) as ParticleEmitter;
67 _particleRenderer = (gameObject.AddComponent<ParticleRenderer>()) as ParticleRenderer;
68 _particleAnimator = (gameObject.AddComponent<ParticleAnimator>()) as ParticleAnimator;
69
70 _particleEmitter.hideFlags = HideFlags.HideAndDontSave;
71 _particleRenderer.hideFlags = HideFlags.HideAndDontSave;
72 _particleAnimator.hideFlags = HideFlags.HideAndDontSave;
73
74 _particleAnimator.damping = _baseDamping;
75
76 _particleEmitter.emit = false;
77 _particleRenderer.maxParticleSize = maxScreenSize;
78 _particleRenderer.material = material;
79 _particleRenderer.material.color = Color.white; //workaround for this not being settable elsewhere
80 _particleAnimator.sizeGrow = sizeGrow;
81
82 if (explodeOnAwake)
83 {
84 Explode();
85 }
86 }
87
88 private float _emitTime;
89 private float speed = 3.0f;
90 private float initFraction = 0.1f;
91 static float epsilon = 0.01f;
92
93 void Update ()
94 {
95 //do exponential particle scaling once emitted
96 if (exponentialGrowth)
97 {
98 float elapsed = Time.time - _emitTime;
99 float oldSize = SizeFunction(elapsed - epsilon);
100 float newSize = SizeFunction(elapsed);
101 float growth = ((newSize / oldSize) - 1) / epsilon;
102 _particleAnimator.sizeGrow = growth;
103 }
104 else
105 {
106 _particleAnimator.sizeGrow = sizeGrow;
107 }
108
109 //delayed explosion
110 if (_delayedExplosionStarted)
111 {
112 _explodeDelay = (_explodeDelay - Time.deltaTime);
113 if (_explodeDelay <= 0f)
114 {
115 Explode();
116 }
117 }
118 }
119
120 private float SizeFunction (float elapsedTime)
121 {
122 float divided = 1 - (1 / (1 + elapsedTime * speed));
123 return initFraction + (1 - initFraction) * divided;
124 }
125
126 public void Reset()
127 {
128 size = _baseSize;
129 color = _baseColor;
130 damping = _baseDamping;
131 }
132
133
134 private float _tmpParticleSize; //calculated particle size... particleSize * randomized size (by sizeVariation)
135 private Vector3 _tmpPos; //calculated position... randomized inside sphere of incoming radius * size
136 private Vector3 _tmpDir; //calculated velocity - randomized inside sphere - incoming velocity * size
137 private Vector3 _thisPos; //handle on this gameobject's position, set inside
138 private float _tmpDuration; //calculated duration... incoming duration * incoming timescale
139 private float _tmpCount; //calculated count... incoming count * incoming detail
140 private float _scaledDuration; //calculated duration... duration * timescale
141 private float _scaledDurationVariation;
142 private float _scaledStartRadius;
143 private float _scaledColor; //color with alpha adjusted according to detail and duration
144 private float _randomizedRotation;
145 private float _tmpAngularVelocity; //random angular velocity from -angularVelocity to +angularVelocity, if randomRotation is true;
146
147 override public void Explode()
148 {
149 if (on)
150 {
151 _particleEmitter.useWorldSpace = useWorldSpace;
152
153 _scaledDuration = timeScale * duration;
154 _scaledDurationVariation = timeScale * durationVariation;
155 _scaledStartRadius = size * startRadius;
156
157 _particleRenderer.particleRenderMode = renderMode;
158
159 if (!_delayedExplosionStarted)
160 {
161 _explodeDelay = explodeDelayMin + (Random.value * (explodeDelayMax - explodeDelayMin));
162 }
163 if (_explodeDelay <= 0)
164 {
165 Color[] modifiedColors = _particleAnimator.colorAnimation;
166
167 if (useExplicitColorAnimation)
168 {
169 modifiedColors[0] = colorAnimation[0];
170 modifiedColors[1] = colorAnimation[1];
171 modifiedColors[2] = colorAnimation[2];
172 modifiedColors[3] = colorAnimation[3];
173 modifiedColors[4] = colorAnimation[4];
174 }
175 else //auto fade
176 {
177 modifiedColors[0] = new Color(color.r, color.g, color.b, (color.a * .7f));
178 modifiedColors[1] = new Color(color.r, color.g, color.b, (color.a * 1f));
179 modifiedColors[2] = new Color(color.r, color.g, color.b, (color.a * .5f));
180 modifiedColors[3] = new Color(color.r, color.g, color.b, (color.a * .3f));
181 modifiedColors[4] = new Color(color.r, color.g, color.b, (color.a * 0f));
182 }
183 _particleAnimator.colorAnimation = modifiedColors;
184 _particleRenderer.material = material;
185 _particleAnimator.force = force;
186 _tmpCount = count * detail;
187 if (_tmpCount < 1) _tmpCount = 1;
188
189 if (_particleEmitter.useWorldSpace == true)
190 {
191 _thisPos = this.gameObject.transform.position;
192 }
193 else
194 {
195 _thisPos = new Vector3(0,0,0);
196 }
197
198 for (int i = 1; i <= _tmpCount; i++)
199 {
200 _tmpPos = Vector3.Scale(Random.insideUnitSphere, new Vector3(_scaledStartRadius, _scaledStartRadius, _scaledStartRadius));
201 _tmpPos = _thisPos + _tmpPos;
202
203 _tmpDir = Vector3.Scale(Random.insideUnitSphere, new Vector3(velocity.x, velocity.y, velocity.z));
204 _tmpDir.y = (_tmpDir.y + (2 * (Mathf.Abs(_tmpDir.y) * upwardsBias)));
205
206 if (randomRotation == true)
207 {
208 _randomizedRotation = Random.Range(-1f,1f);
209 _tmpAngularVelocity = Random.Range(-1f,1f) * angularVelocity;
210
211 }
212 else
213 {
214 _randomizedRotation = 0f;
215 _tmpAngularVelocity = angularVelocity;
216 }
217
218 _tmpDir = Vector3.Scale(_tmpDir, new Vector3(size, size, size));
219
220 _tmpParticleSize = size * (particleSize + (Random.value * sizeVariation));
221
222 _tmpDuration = _scaledDuration + (Random.value * _scaledDurationVariation);
223 _particleEmitter.Emit(_tmpPos, _tmpDir, _tmpParticleSize, _tmpDuration, color, _randomizedRotation, _tmpAngularVelocity);
224 }
225
226 _emitTime = Time.time;
227 _delayedExplosionStarted = false;
228 _explodeDelay = 0f;
229 }
230 else
231 {
232 //tell update to start reducing the start delay and call explode again when it's zero
233 _delayedExplosionStarted = true;
234 }
235 }
236 }
237
238 }