123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- //
- // Rain Maker (c) 2015 Digital Ruby, LLC
- // http://www.digitalruby.com
- //
- using UnityEngine;
- using System.Collections;
- namespace DigitalRuby.RainMaker
- {
- public class RainScript2D : BaseRainScript
- {
- private static readonly Color32 explosionColor = new Color32(255, 255, 255, 255);
- private float cameraMultiplier = 1.0f;
- private Bounds visibleBounds = new Bounds();
- private float yOffset;
- private float visibleWorldWidth;
- private float initialEmissionRain;
- private Vector2 initialStartSpeedRain;
- private Vector2 initialStartSizeRain;
- private Vector2 initialStartSpeedMist;
- private Vector2 initialStartSizeMist;
- private Vector2 initialStartSpeedExplosion;
- private Vector2 initialStartSizeExplosion;
- private readonly ParticleSystem.Particle[] particles = new ParticleSystem.Particle[2048];
- [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.")]
- public float RainHeightMultiplier = 0.15f;
- [Tooltip("The total width of the rain and mist as a percentage of visible width")]
- public float RainWidthMultiplier = 1.5f;
- [Tooltip("Collision mask for the rain particles")]
- public LayerMask CollisionMask = -1;
- [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.")]
- [Range(0.0f, 0.5f)]
- public float CollisionLifeTimeRain = 0.02f;
- [Tooltip("Multiply the velocity of any mist colliding by this amount")]
- [Range(0.0f, 0.99f)]
- public float RainMistCollisionMultiplier = 0.75f;
- private void EmitExplosion(ref Vector3 pos)
- {
- int count = UnityEngine.Random.Range(2, 5);
- while (count != 0)
- {
- float xVelocity = UnityEngine.Random.Range(-2.0f, 2.0f) * cameraMultiplier;
- float yVelocity = UnityEngine.Random.Range(1.0f, 3.0f) * cameraMultiplier;
- float lifetime = UnityEngine.Random.Range(0.1f, 0.2f);
- float size = UnityEngine.Random.Range(0.05f, 0.1f) * cameraMultiplier;
- ParticleSystem.EmitParams param = new ParticleSystem.EmitParams();
- param.position = pos;
- param.velocity = new Vector3(xVelocity, yVelocity, 0.0f);
- param.startLifetime = lifetime;
- param.startSize = size;
- param.startColor = explosionColor;
- RainExplosionParticleSystem.Emit(param, 1);
- count--;
- }
- }
- private void TransformParticleSystem(ParticleSystem p, Vector2 initialStartSpeed, Vector2 initialStartSize)
- {
- if (p == null)
- {
- return;
- }
- if (FollowCamera)
- {
- p.transform.position = new Vector3(Camera.transform.position.x, visibleBounds.max.y + yOffset, p.transform.position.z);
- }
- else
- {
- p.transform.position = new Vector3(p.transform.position.x, visibleBounds.max.y + yOffset, p.transform.position.z);
- }
- p.transform.localScale = new Vector3(visibleWorldWidth * RainWidthMultiplier, 1.0f, 1.0f);
- var m = p.main;
- var speed = m.startSpeed;
- var size = m.startSize;
- speed.constantMin = initialStartSpeed.x * cameraMultiplier;
- speed.constantMax = initialStartSpeed.y * cameraMultiplier;
- size.constantMin = initialStartSize.x * cameraMultiplier;
- size.constantMax = initialStartSize.y * cameraMultiplier;
- m.startSpeed = speed;
- m.startSize = size;
- }
- private void CheckForCollisionsRainParticles()
- {
- int count = 0;
- bool changes = false;
- if (CollisionMask != 0)
- {
- count = RainFallParticleSystem.GetParticles(particles);
- RaycastHit2D hit;
- for (int i = 0; i < count; i++)
- {
- Vector3 pos = particles[i].position + RainFallParticleSystem.transform.position;
- hit = Physics2D.Raycast(pos, particles[i].velocity.normalized, particles[i].velocity.magnitude * Time.deltaTime);
- if (hit.collider != null && ((1 << hit.collider.gameObject.layer) & CollisionMask) != 0)
- {
- if (CollisionLifeTimeRain == 0.0f)
- {
- particles[i].remainingLifetime = 0.0f;
- }
- else
- {
- particles[i].remainingLifetime = Mathf.Min(particles[i].remainingLifetime, UnityEngine.Random.Range(CollisionLifeTimeRain * 0.5f, CollisionLifeTimeRain * 2.0f));
- pos += (particles[i].velocity * Time.deltaTime);
- }
- changes = true;
- }
- }
- }
- if (RainExplosionParticleSystem != null)
- {
- if (count == 0)
- {
- count = RainFallParticleSystem.GetParticles(particles);
- }
- for (int i = 0; i < count; i++)
- {
- if (particles[i].remainingLifetime < 0.24f)
- {
- Vector3 pos = particles[i].position + RainFallParticleSystem.transform.position;
- EmitExplosion(ref pos);
- }
- }
- }
- if (changes)
- {
- RainFallParticleSystem.SetParticles(particles, count);
- }
- }
- private void CheckForCollisionsMistParticles()
- {
- if (RainMistParticleSystem == null || CollisionMask == 0)
- {
- return;
- }
- int count = RainMistParticleSystem.GetParticles(particles);
- bool changes = false;
- RaycastHit2D hit;
- for (int i = 0; i < count; i++)
- {
- Vector3 pos = particles[i].position + RainMistParticleSystem.transform.position;
- hit = Physics2D.Raycast(pos, particles[i].velocity.normalized, particles[i].velocity.magnitude* Time.deltaTime, CollisionMask);
- if (hit.collider != null)
- {
- particles[i].velocity *= RainMistCollisionMultiplier;
- changes = true;
- }
- }
- if (changes)
- {
- RainMistParticleSystem.SetParticles(particles, count);
- }
- }
- protected override void Start()
- {
- base.Start();
- initialEmissionRain = RainFallParticleSystem.emission.rateOverTime.constant;
- initialStartSpeedRain = new Vector2(RainFallParticleSystem.main.startSpeed.constantMin, RainFallParticleSystem.main.startSpeed.constantMax);
- initialStartSizeRain = new Vector2(RainFallParticleSystem.main.startSize.constantMin, RainFallParticleSystem.main.startSize.constantMax);
- if (RainMistParticleSystem != null)
- {
- initialStartSpeedMist = new Vector2(RainMistParticleSystem.main.startSpeed.constantMin, RainMistParticleSystem.main.startSpeed.constantMax);
- initialStartSizeMist = new Vector2(RainMistParticleSystem.main.startSize.constantMin, RainMistParticleSystem.main.startSize.constantMax);
- }
- if (RainExplosionParticleSystem != null)
- {
- initialStartSpeedExplosion = new Vector2(RainExplosionParticleSystem.main.startSpeed.constantMin, RainExplosionParticleSystem.main.startSpeed.constantMax);
- initialStartSizeExplosion = new Vector2(RainExplosionParticleSystem.main.startSize.constantMin, RainExplosionParticleSystem.main.startSize.constantMax);
- }
- }
- protected override void Update()
- {
- base.Update();
- cameraMultiplier = (Camera.orthographicSize * 0.25f);
- visibleBounds.min = Camera.main.ViewportToWorldPoint(Vector3.zero);
- visibleBounds.max = Camera.main.ViewportToWorldPoint(Vector3.one);
- visibleWorldWidth = visibleBounds.size.x;
- yOffset = (visibleBounds.max.y - visibleBounds.min.y) * RainHeightMultiplier;
- TransformParticleSystem(RainFallParticleSystem, initialStartSpeedRain, initialStartSizeRain);
- TransformParticleSystem(RainMistParticleSystem, initialStartSpeedMist, initialStartSizeMist);
- TransformParticleSystem(RainExplosionParticleSystem, initialStartSpeedExplosion, initialStartSizeExplosion);
- CheckForCollisionsRainParticles();
- CheckForCollisionsMistParticles();
- }
- protected override float RainFallEmissionRate()
- {
- return initialEmissionRain * RainIntensity;
- }
- protected override bool UseRainMistSoftParticles
- {
- get
- {
- return false;
- }
- }
- }
- }
|