RainScript2D.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. //
  2. // Rain Maker (c) 2015 Digital Ruby, LLC
  3. // http://www.digitalruby.com
  4. //
  5. using UnityEngine;
  6. using System.Collections;
  7. namespace DigitalRuby.RainMaker
  8. {
  9. public class RainScript2D : BaseRainScript
  10. {
  11. private static readonly Color32 explosionColor = new Color32(255, 255, 255, 255);
  12. private float cameraMultiplier = 1.0f;
  13. private Bounds visibleBounds = new Bounds();
  14. private float yOffset;
  15. private float visibleWorldWidth;
  16. private float initialEmissionRain;
  17. private Vector2 initialStartSpeedRain;
  18. private Vector2 initialStartSizeRain;
  19. private Vector2 initialStartSpeedMist;
  20. private Vector2 initialStartSizeMist;
  21. private Vector2 initialStartSpeedExplosion;
  22. private Vector2 initialStartSizeExplosion;
  23. private readonly ParticleSystem.Particle[] particles = new ParticleSystem.Particle[2048];
  24. [Tooltip("The starting y offset for rain and mist. This will be offset as a percentage of visible height from the top of the visible world.")]
  25. public float RainHeightMultiplier = 0.15f;
  26. [Tooltip("The total width of the rain and mist as a percentage of visible width")]
  27. public float RainWidthMultiplier = 1.5f;
  28. [Tooltip("Collision mask for the rain particles")]
  29. public LayerMask CollisionMask = -1;
  30. [Tooltip("Lifetime to assign to rain particles that have collided. 0 for instant death. This can allow the rain to penetrate a little bit beyond the collision point.")]
  31. [Range(0.0f, 0.5f)]
  32. public float CollisionLifeTimeRain = 0.02f;
  33. [Tooltip("Multiply the velocity of any mist colliding by this amount")]
  34. [Range(0.0f, 0.99f)]
  35. public float RainMistCollisionMultiplier = 0.75f;
  36. private void EmitExplosion(ref Vector3 pos)
  37. {
  38. int count = UnityEngine.Random.Range(2, 5);
  39. while (count != 0)
  40. {
  41. float xVelocity = UnityEngine.Random.Range(-2.0f, 2.0f) * cameraMultiplier;
  42. float yVelocity = UnityEngine.Random.Range(1.0f, 3.0f) * cameraMultiplier;
  43. float lifetime = UnityEngine.Random.Range(0.1f, 0.2f);
  44. float size = UnityEngine.Random.Range(0.05f, 0.1f) * cameraMultiplier;
  45. ParticleSystem.EmitParams param = new ParticleSystem.EmitParams();
  46. param.position = pos;
  47. param.velocity = new Vector3(xVelocity, yVelocity, 0.0f);
  48. param.startLifetime = lifetime;
  49. param.startSize = size;
  50. param.startColor = explosionColor;
  51. RainExplosionParticleSystem.Emit(param, 1);
  52. count--;
  53. }
  54. }
  55. private void TransformParticleSystem(ParticleSystem p, Vector2 initialStartSpeed, Vector2 initialStartSize)
  56. {
  57. if (p == null)
  58. {
  59. return;
  60. }
  61. if (FollowCamera)
  62. {
  63. p.transform.position = new Vector3(Camera.transform.position.x, visibleBounds.max.y + yOffset, p.transform.position.z);
  64. }
  65. else
  66. {
  67. p.transform.position = new Vector3(p.transform.position.x, visibleBounds.max.y + yOffset, p.transform.position.z);
  68. }
  69. p.transform.localScale = new Vector3(visibleWorldWidth * RainWidthMultiplier, 1.0f, 1.0f);
  70. var m = p.main;
  71. var speed = m.startSpeed;
  72. var size = m.startSize;
  73. speed.constantMin = initialStartSpeed.x * cameraMultiplier;
  74. speed.constantMax = initialStartSpeed.y * cameraMultiplier;
  75. size.constantMin = initialStartSize.x * cameraMultiplier;
  76. size.constantMax = initialStartSize.y * cameraMultiplier;
  77. m.startSpeed = speed;
  78. m.startSize = size;
  79. }
  80. private void CheckForCollisionsRainParticles()
  81. {
  82. int count = 0;
  83. bool changes = false;
  84. if (CollisionMask != 0)
  85. {
  86. count = RainFallParticleSystem.GetParticles(particles);
  87. RaycastHit2D hit;
  88. for (int i = 0; i < count; i++)
  89. {
  90. Vector3 pos = particles[i].position + RainFallParticleSystem.transform.position;
  91. hit = Physics2D.Raycast(pos, particles[i].velocity.normalized, particles[i].velocity.magnitude * Time.deltaTime);
  92. if (hit.collider != null && ((1 << hit.collider.gameObject.layer) & CollisionMask) != 0)
  93. {
  94. if (CollisionLifeTimeRain == 0.0f)
  95. {
  96. particles[i].remainingLifetime = 0.0f;
  97. }
  98. else
  99. {
  100. particles[i].remainingLifetime = Mathf.Min(particles[i].remainingLifetime, UnityEngine.Random.Range(CollisionLifeTimeRain * 0.5f, CollisionLifeTimeRain * 2.0f));
  101. pos += (particles[i].velocity * Time.deltaTime);
  102. }
  103. changes = true;
  104. }
  105. }
  106. }
  107. if (RainExplosionParticleSystem != null)
  108. {
  109. if (count == 0)
  110. {
  111. count = RainFallParticleSystem.GetParticles(particles);
  112. }
  113. for (int i = 0; i < count; i++)
  114. {
  115. if (particles[i].remainingLifetime < 0.24f)
  116. {
  117. Vector3 pos = particles[i].position + RainFallParticleSystem.transform.position;
  118. EmitExplosion(ref pos);
  119. }
  120. }
  121. }
  122. if (changes)
  123. {
  124. RainFallParticleSystem.SetParticles(particles, count);
  125. }
  126. }
  127. private void CheckForCollisionsMistParticles()
  128. {
  129. if (RainMistParticleSystem == null || CollisionMask == 0)
  130. {
  131. return;
  132. }
  133. int count = RainMistParticleSystem.GetParticles(particles);
  134. bool changes = false;
  135. RaycastHit2D hit;
  136. for (int i = 0; i < count; i++)
  137. {
  138. Vector3 pos = particles[i].position + RainMistParticleSystem.transform.position;
  139. hit = Physics2D.Raycast(pos, particles[i].velocity.normalized, particles[i].velocity.magnitude* Time.deltaTime, CollisionMask);
  140. if (hit.collider != null)
  141. {
  142. particles[i].velocity *= RainMistCollisionMultiplier;
  143. changes = true;
  144. }
  145. }
  146. if (changes)
  147. {
  148. RainMistParticleSystem.SetParticles(particles, count);
  149. }
  150. }
  151. protected override void Start()
  152. {
  153. base.Start();
  154. initialEmissionRain = RainFallParticleSystem.emission.rateOverTime.constant;
  155. initialStartSpeedRain = new Vector2(RainFallParticleSystem.main.startSpeed.constantMin, RainFallParticleSystem.main.startSpeed.constantMax);
  156. initialStartSizeRain = new Vector2(RainFallParticleSystem.main.startSize.constantMin, RainFallParticleSystem.main.startSize.constantMax);
  157. if (RainMistParticleSystem != null)
  158. {
  159. initialStartSpeedMist = new Vector2(RainMistParticleSystem.main.startSpeed.constantMin, RainMistParticleSystem.main.startSpeed.constantMax);
  160. initialStartSizeMist = new Vector2(RainMistParticleSystem.main.startSize.constantMin, RainMistParticleSystem.main.startSize.constantMax);
  161. }
  162. if (RainExplosionParticleSystem != null)
  163. {
  164. initialStartSpeedExplosion = new Vector2(RainExplosionParticleSystem.main.startSpeed.constantMin, RainExplosionParticleSystem.main.startSpeed.constantMax);
  165. initialStartSizeExplosion = new Vector2(RainExplosionParticleSystem.main.startSize.constantMin, RainExplosionParticleSystem.main.startSize.constantMax);
  166. }
  167. }
  168. protected override void Update()
  169. {
  170. base.Update();
  171. cameraMultiplier = (Camera.orthographicSize * 0.25f);
  172. visibleBounds.min = Camera.main.ViewportToWorldPoint(Vector3.zero);
  173. visibleBounds.max = Camera.main.ViewportToWorldPoint(Vector3.one);
  174. visibleWorldWidth = visibleBounds.size.x;
  175. yOffset = (visibleBounds.max.y - visibleBounds.min.y) * RainHeightMultiplier;
  176. TransformParticleSystem(RainFallParticleSystem, initialStartSpeedRain, initialStartSizeRain);
  177. TransformParticleSystem(RainMistParticleSystem, initialStartSpeedMist, initialStartSizeMist);
  178. TransformParticleSystem(RainExplosionParticleSystem, initialStartSpeedExplosion, initialStartSizeExplosion);
  179. CheckForCollisionsRainParticles();
  180. CheckForCollisionsMistParticles();
  181. }
  182. protected override float RainFallEmissionRate()
  183. {
  184. return initialEmissionRain * RainIntensity;
  185. }
  186. protected override bool UseRainMistSoftParticles
  187. {
  188. get
  189. {
  190. return false;
  191. }
  192. }
  193. }
  194. }