using System; using System.Collections.Generic; using UnityEngine; namespace SUISSEngine { public class LinearParticles : MonoBehaviour { private void Start() { for (int i = 0; i < this.initialParticleCount; i++) { LinearParticles.Particle particle = this.CreateParticle(); this.RandomizeParticle(particle); } this.SetNextSpawnTime(); } private void Update() { if (this.spawnMethod == LinearParticles.SpawnMethod.Delayed) { while (Time.time >= this.nextSpawnTime) { LinearParticles.Particle particle = this.CreateParticle(); this.RandomizeParticle(particle); this.MoveParticleToStart(particle); this.SetNextSpawnTime(); } } Bounds bounds = default(Bounds); bounds.center = base.transform.TransformPoint(this.bounds.center); bounds.extents = base.transform.TransformDirection(this.bounds.extents); List list = null; foreach (LinearParticles.Particle particle2 in this.particles) { if (particle2 != null) { Vector3 localPosition = particle2.gameObject.transform.localPosition; localPosition.x += particle2.velocity.x * Time.deltaTime; localPosition.y += particle2.velocity.y * Time.deltaTime; particle2.gameObject.transform.localPosition = localPosition; Bounds bounds2 = default(Bounds); if (particle2.spriteRenderer == null) { bounds2.center = particle2.gameObject.transform.position; bounds2.extents = Vector3.zero; } else { bounds2 = particle2.spriteRenderer.bounds; } if (!bounds.Intersects(bounds2)) { if (this.spawnMethod == LinearParticles.SpawnMethod.Delayed) { if (list == null) { list = new List(); } list.Add(particle2); } else { if (this.spawnMethod != LinearParticles.SpawnMethod.Reuse) { throw new InvalidOperationException("Invalid spawn method"); } this.RandomizeParticle(particle2); this.MoveParticleToStart(particle2); } } } } if (list != null) { foreach (LinearParticles.Particle particle3 in list) { this.particles.Remove(particle3); UnityEngine.Object.Destroy(particle3.gameObject); } } } private LinearParticles.Particle CreateParticle() { LinearParticles.Particle particle = null; if (this.prefabs != null && this.prefabs.Length > 0) { GameObject gameObject = null; if (this.prefabChoice == LinearParticles.PrefabChoice.Random) { gameObject = this.prefabs[UnityEngine.Random.Range(0, this.prefabs.Length)]; } else if (this.prefabChoice == LinearParticles.PrefabChoice.Cycle) { gameObject = this.prefabs[this.nextPrefabIndex]; this.nextPrefabIndex = (this.nextPrefabIndex + 1) % this.prefabs.Length; } if (gameObject != null) { GameObject gameObject2 = UnityEngine.Object.Instantiate(gameObject); gameObject2.transform.parent = base.transform; particle = new LinearParticles.Particle(); particle.gameObject = gameObject2; particle.spriteRenderer = gameObject2.GetComponent(); this.particles.Add(particle); } } return particle; } private void RandomizeParticle(LinearParticles.Particle particle) { Vector3 center = this.bounds.center; center.x += (UnityEngine.Random.value - 0.5f) * this.bounds.size.x; center.y += (UnityEngine.Random.value - 0.5f) * this.bounds.size.y; center.z += (UnityEngine.Random.value - 0.5f) * this.bounds.size.z; particle.gameObject.transform.localPosition = center; float num = UnityEngine.Random.Range(this.minScale, this.maxScale); particle.gameObject.transform.localScale = new Vector3(num, num, 1f); particle.velocity = this.direction.normalized * UnityEngine.Random.Range(this.minSpeed, this.maxSpeed); if (this.angleVariation != 0f) { Vector3 point = new Vector3(particle.velocity.x, particle.velocity.y, 0f); float angle = this.angleVariation * (UnityEngine.Random.value - 0.5f); Quaternion rotation = Quaternion.AngleAxis(angle, new Vector3(0f, 0f, 1f)); point = rotation * point; particle.velocity = new Vector2(point.x, point.y); } } private void MoveParticleToStart(LinearParticles.Particle particle) { Bounds bounds = default(Bounds); bounds.center = base.transform.TransformPoint(this.bounds.center); bounds.extents = base.transform.TransformDirection(this.bounds.extents); Bounds bounds2 = default(Bounds); if (particle.spriteRenderer == null) { bounds2.center = particle.gameObject.transform.position; bounds2.extents = Vector3.zero; } else { bounds2 = particle.spriteRenderer.bounds; } if (!bounds.Intersects(bounds2)) { return; } Vector3 vector = -particle.velocity.normalized; Bounds bounds3 = bounds2; float num = 0f; float num2 = (bounds.extents.x + bounds.extents.y) * 0.5f; bounds3.center = new Vector3(bounds2.center.x + vector.x * num2, bounds2.center.y + vector.y * num2, bounds2.center.z); while (bounds.Intersects(bounds3)) { num = num2; num2 *= 2f; bounds3.center = new Vector3(bounds2.center.x + vector.x * num2, bounds2.center.y + vector.y * num2, bounds2.center.z); } float num3 = 1f / this.island.pixelsPerUnit; while (num2 - num > num3) { float num4 = (num + num2) * 0.5f; bounds3.center = new Vector3(bounds2.center.x + vector.x * num4, bounds2.center.y + vector.y * num4, bounds2.center.z); if (bounds.Intersects(bounds3)) { num = num4; } else { num2 = num4; } } Vector3 localPosition = particle.gameObject.transform.localPosition; localPosition.x += vector.x * num; localPosition.y += vector.y * num; particle.gameObject.transform.localPosition = localPosition; } private void SetNextSpawnTime() { this.nextSpawnTime = Time.time + UnityEngine.Random.Range(this.minDelay, this.maxDelay); } public int initialParticleCount; public GameObject[] prefabs; public LinearParticles.PrefabChoice prefabChoice; public LinearParticles.SpawnMethod spawnMethod; public float minDelay = 1f; public float maxDelay = 1f; public Bounds bounds = new Bounds(Vector3.zero, Vector3.zero); public float minScale = 1f; public float maxScale = 1f; public Vector2 direction = new Vector2(1f, 0f); public float angleVariation; public float minSpeed = 1f; public float maxSpeed = 1f; [ParentReference] public IsometricIsland island; private List particles = new List(); private int nextPrefabIndex; private float nextSpawnTime; public enum PrefabChoice { Random, Cycle } public enum SpawnMethod { Delayed, Reuse } private class Particle { public GameObject gameObject; public SpriteRenderer spriteRenderer; public Vector2 velocity; } } }