You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

245 lines
7.1 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace SUISSEngine
  5. {
  6. public class LinearParticles : MonoBehaviour
  7. {
  8. private void Start()
  9. {
  10. for (int i = 0; i < this.initialParticleCount; i++)
  11. {
  12. LinearParticles.Particle particle = this.CreateParticle();
  13. this.RandomizeParticle(particle);
  14. }
  15. this.SetNextSpawnTime();
  16. }
  17. private void Update()
  18. {
  19. if (this.spawnMethod == LinearParticles.SpawnMethod.Delayed)
  20. {
  21. while (Time.time >= this.nextSpawnTime)
  22. {
  23. LinearParticles.Particle particle = this.CreateParticle();
  24. this.RandomizeParticle(particle);
  25. this.MoveParticleToStart(particle);
  26. this.SetNextSpawnTime();
  27. }
  28. }
  29. Bounds bounds = default(Bounds);
  30. bounds.center = base.transform.TransformPoint(this.bounds.center);
  31. bounds.extents = base.transform.TransformDirection(this.bounds.extents);
  32. List<LinearParticles.Particle> list = null;
  33. foreach (LinearParticles.Particle particle2 in this.particles)
  34. {
  35. if (particle2 != null)
  36. {
  37. Vector3 localPosition = particle2.gameObject.transform.localPosition;
  38. localPosition.x += particle2.velocity.x * Time.deltaTime;
  39. localPosition.y += particle2.velocity.y * Time.deltaTime;
  40. particle2.gameObject.transform.localPosition = localPosition;
  41. Bounds bounds2 = default(Bounds);
  42. if (particle2.spriteRenderer == null)
  43. {
  44. bounds2.center = particle2.gameObject.transform.position;
  45. bounds2.extents = Vector3.zero;
  46. }
  47. else
  48. {
  49. bounds2 = particle2.spriteRenderer.bounds;
  50. }
  51. if (!bounds.Intersects(bounds2))
  52. {
  53. if (this.spawnMethod == LinearParticles.SpawnMethod.Delayed)
  54. {
  55. if (list == null)
  56. {
  57. list = new List<LinearParticles.Particle>();
  58. }
  59. list.Add(particle2);
  60. }
  61. else
  62. {
  63. if (this.spawnMethod != LinearParticles.SpawnMethod.Reuse)
  64. {
  65. throw new InvalidOperationException("Invalid spawn method");
  66. }
  67. this.RandomizeParticle(particle2);
  68. this.MoveParticleToStart(particle2);
  69. }
  70. }
  71. }
  72. }
  73. if (list != null)
  74. {
  75. foreach (LinearParticles.Particle particle3 in list)
  76. {
  77. this.particles.Remove(particle3);
  78. UnityEngine.Object.Destroy(particle3.gameObject);
  79. }
  80. }
  81. }
  82. private LinearParticles.Particle CreateParticle()
  83. {
  84. LinearParticles.Particle particle = null;
  85. if (this.prefabs != null && this.prefabs.Length > 0)
  86. {
  87. GameObject gameObject = null;
  88. if (this.prefabChoice == LinearParticles.PrefabChoice.Random)
  89. {
  90. gameObject = this.prefabs[UnityEngine.Random.Range(0, this.prefabs.Length)];
  91. }
  92. else if (this.prefabChoice == LinearParticles.PrefabChoice.Cycle)
  93. {
  94. gameObject = this.prefabs[this.nextPrefabIndex];
  95. this.nextPrefabIndex = (this.nextPrefabIndex + 1) % this.prefabs.Length;
  96. }
  97. if (gameObject != null)
  98. {
  99. GameObject gameObject2 = UnityEngine.Object.Instantiate<GameObject>(gameObject);
  100. gameObject2.transform.parent = base.transform;
  101. particle = new LinearParticles.Particle();
  102. particle.gameObject = gameObject2;
  103. particle.spriteRenderer = gameObject2.GetComponent<SpriteRenderer>();
  104. this.particles.Add(particle);
  105. }
  106. }
  107. return particle;
  108. }
  109. private void RandomizeParticle(LinearParticles.Particle particle)
  110. {
  111. Vector3 center = this.bounds.center;
  112. center.x += (UnityEngine.Random.value - 0.5f) * this.bounds.size.x;
  113. center.y += (UnityEngine.Random.value - 0.5f) * this.bounds.size.y;
  114. center.z += (UnityEngine.Random.value - 0.5f) * this.bounds.size.z;
  115. particle.gameObject.transform.localPosition = center;
  116. float num = UnityEngine.Random.Range(this.minScale, this.maxScale);
  117. particle.gameObject.transform.localScale = new Vector3(num, num, 1f);
  118. particle.velocity = this.direction.normalized * UnityEngine.Random.Range(this.minSpeed, this.maxSpeed);
  119. if (this.angleVariation != 0f)
  120. {
  121. Vector3 point = new Vector3(particle.velocity.x, particle.velocity.y, 0f);
  122. float angle = this.angleVariation * (UnityEngine.Random.value - 0.5f);
  123. Quaternion rotation = Quaternion.AngleAxis(angle, new Vector3(0f, 0f, 1f));
  124. point = rotation * point;
  125. particle.velocity = new Vector2(point.x, point.y);
  126. }
  127. }
  128. private void MoveParticleToStart(LinearParticles.Particle particle)
  129. {
  130. Bounds bounds = default(Bounds);
  131. bounds.center = base.transform.TransformPoint(this.bounds.center);
  132. bounds.extents = base.transform.TransformDirection(this.bounds.extents);
  133. Bounds bounds2 = default(Bounds);
  134. if (particle.spriteRenderer == null)
  135. {
  136. bounds2.center = particle.gameObject.transform.position;
  137. bounds2.extents = Vector3.zero;
  138. }
  139. else
  140. {
  141. bounds2 = particle.spriteRenderer.bounds;
  142. }
  143. if (!bounds.Intersects(bounds2))
  144. {
  145. return;
  146. }
  147. Vector3 vector = -particle.velocity.normalized;
  148. Bounds bounds3 = bounds2;
  149. float num = 0f;
  150. float num2 = (bounds.extents.x + bounds.extents.y) * 0.5f;
  151. bounds3.center = new Vector3(bounds2.center.x + vector.x * num2, bounds2.center.y + vector.y * num2, bounds2.center.z);
  152. while (bounds.Intersects(bounds3))
  153. {
  154. num = num2;
  155. num2 *= 2f;
  156. bounds3.center = new Vector3(bounds2.center.x + vector.x * num2, bounds2.center.y + vector.y * num2, bounds2.center.z);
  157. }
  158. float num3 = 1f / this.island.pixelsPerUnit;
  159. while (num2 - num > num3)
  160. {
  161. float num4 = (num + num2) * 0.5f;
  162. bounds3.center = new Vector3(bounds2.center.x + vector.x * num4, bounds2.center.y + vector.y * num4, bounds2.center.z);
  163. if (bounds.Intersects(bounds3))
  164. {
  165. num = num4;
  166. }
  167. else
  168. {
  169. num2 = num4;
  170. }
  171. }
  172. Vector3 localPosition = particle.gameObject.transform.localPosition;
  173. localPosition.x += vector.x * num;
  174. localPosition.y += vector.y * num;
  175. particle.gameObject.transform.localPosition = localPosition;
  176. }
  177. private void SetNextSpawnTime()
  178. {
  179. this.nextSpawnTime = Time.time + UnityEngine.Random.Range(this.minDelay, this.maxDelay);
  180. }
  181. public int initialParticleCount;
  182. public GameObject[] prefabs;
  183. public LinearParticles.PrefabChoice prefabChoice;
  184. public LinearParticles.SpawnMethod spawnMethod;
  185. public float minDelay = 1f;
  186. public float maxDelay = 1f;
  187. public Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
  188. public float minScale = 1f;
  189. public float maxScale = 1f;
  190. public Vector2 direction = new Vector2(1f, 0f);
  191. public float angleVariation;
  192. public float minSpeed = 1f;
  193. public float maxSpeed = 1f;
  194. [ParentReference]
  195. public IsometricIsland island;
  196. private List<LinearParticles.Particle> particles = new List<LinearParticles.Particle>();
  197. private int nextPrefabIndex;
  198. private float nextSpawnTime;
  199. public enum PrefabChoice
  200. {
  201. Random,
  202. Cycle
  203. }
  204. public enum SpawnMethod
  205. {
  206. Delayed,
  207. Reuse
  208. }
  209. private class Particle
  210. {
  211. public GameObject gameObject;
  212. public SpriteRenderer spriteRenderer;
  213. public Vector2 velocity;
  214. }
  215. }
  216. }