< Summary

Class:ParticleManager
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Managers/ParticleManager.cs
Covered lines:0
Uncovered lines:156
Coverable lines:156
Total lines:224
Line coverage:0% (0 of 156)
Covered branches:0
Total branches:0
Covered methods:0
Total methods:24
Method coverage:0% (0 of 24)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ParticleManager()0%2100%
ClearHitMarkers()0%6200%
Awake()0%12300%
Start()0%12300%
Update()0%2100%
InitializeMissileTrailParticlePool()0%6200%
InstantiateMissileTrail(...)0%2100%
InstantiateMissileTrailsOverTime()0%20400%
InitializeMissileExplosionParticlePool()0%6200%
InstantiateMissileExplosion(...)0%2100%
InstantiateMissileExplosionsOverTime()0%20400%
RegisterNewInterceptor(...)0%2100%
RegisterInterceptorHit(...)0%6200%
RegisterInterceptorMiss(...)0%2100%
RegisterNewThreat(...)0%2100%
RegisterAgentTerminated(...)0%6200%
RegisterSimulationEnded()0%6200%
SpawnHitMarker(...)0%2100%
PlayMissileExplosion(...)0%12300%
ReturnExplosionAfterDelay()0%12300%
ReturnMissileExplosionParticle(...)0%12300%
CommandeerAgentTrailRenderer(...)0%20400%

File(s)

/github/workspace/Assets/Scripts/Managers/ParticleManager.cs

#LineLine coverage
 1using System.Collections;
 2using System.Collections.Generic;
 3using UnityEngine;
 4
 5public class ParticleManager : MonoBehaviour {
 06  public static ParticleManager Instance { get; private set; }
 7
 8  private Queue<GameObject> _missileTrailPool;
 9  [SerializeField]
 10  private int _missileTrailPoolCount;
 11  [SerializeField]
 12  private Queue<GameObject> _missileExplosionPool;
 13  [SerializeField]
 14  private int _missileExplosionPoolCount;
 15
 16  [SerializeField]
 017  private List<TrailRenderer> _agentTrailRenderers = new List<TrailRenderer>();
 18
 19  [SerializeField, Tooltip("The material to use for commandeered interceptor trail renderers")]
 20  public Material InterceptorTrailMatFaded;
 21  [SerializeField, Tooltip("The material to use for commandeered threat trail renderers")]
 22  public Material ThreatTrailMatFaded;
 23
 24  [SerializeField]
 025  private List<GameObject> _hitMarkerList = new List<GameObject>();
 26
 027  public void ClearHitMarkers() {
 028    foreach (var hitMarker in _hitMarkerList) {
 029      Destroy(hitMarker);
 030    }
 031    _hitMarkerList.Clear();
 032  }
 33
 034  private void Awake() {
 035    if (Instance != null && Instance != this) {
 036      Destroy(gameObject);
 037      return;
 38    }
 039    Instance = this;
 040    DontDestroyOnLoad(gameObject);
 041  }
 42
 043  private void Start() {
 044    _missileTrailPool = new Queue<GameObject>();
 045    _missileExplosionPool = new Queue<GameObject>();
 046    _hitMarkerList = new List<GameObject>();
 47
 048    if (SimManager.Instance.SimulatorConfig.EnableMissileTrailEffect) {
 049      InitializeMissileTrailParticlePool();
 050    }
 051    if (SimManager.Instance.SimulatorConfig.EnableExplosionEffect) {
 052      InitializeMissileExplosionParticlePool();
 053    }
 54
 55    // Subscribe to events.
 056    SimManager.Instance.OnNewInterceptor += RegisterNewInterceptor;
 057    SimManager.Instance.OnNewThreat += RegisterNewThreat;
 58
 059    SimManager.Instance.OnSimulationEnded += RegisterSimulationEnded;
 060  }
 61
 062  private void Update() {
 063    _missileTrailPoolCount = _missileTrailPool.Count;
 064    _missileExplosionPoolCount = _missileExplosionPool.Count;
 065  }
 66
 067  private void InitializeMissileTrailParticlePool() {
 68    // Grab from Resources/Prefabs/Effects.
 069    GameObject missileTrailPrefab =
 70        Resources.Load<GameObject>("Prefabs/Effects/InterceptorSmokeEffect");
 71
 72    // Pre-instantiate 10 missile trail particles.
 073    for (int i = 0; i < 10; ++i) {
 074      InstantiateMissileTrail(missileTrailPrefab);
 075    }
 76    // Instantiate over an interval.
 077    StartCoroutine(InstantiateMissileTrailsOverTime(missileTrailPrefab, 200, 0.05f));
 078  }
 79
 080  private GameObject InstantiateMissileTrail(GameObject prefab) {
 081    GameObject trail = Instantiate(prefab, transform);
 082    trail.GetComponent<ParticleSystem>().Stop();
 083    _missileTrailPool.Enqueue(trail);
 084    return trail;
 085  }
 86
 87  private IEnumerator InstantiateMissileTrailsOverTime(GameObject prefab, int count,
 088                                                       float duration) {
 089    float interval = duration / count;
 090    for (int i = 0; i < count; ++i) {
 091      InstantiateMissileTrail(prefab);
 092      yield return new WaitForSeconds(interval);
 093    }
 094  }
 95
 096  private void InitializeMissileExplosionParticlePool() {
 097    GameObject missileExplosionPrefab =
 98        Resources.Load<GameObject>("Prefabs/Effects/InterceptExplosionEffect");
 99    // Pre-instantiate 10 missile trail particles.
 0100    for (int i = 0; i < 10; ++i) {
 0101      InstantiateMissileExplosion(missileExplosionPrefab);
 0102    }
 0103    StartCoroutine(InstantiateMissileExplosionsOverTime(missileExplosionPrefab, 200, 0.05f));
 0104  }
 105
 0106  private GameObject InstantiateMissileExplosion(GameObject prefab) {
 0107    GameObject explosion = Instantiate(prefab, transform);
 0108    explosion.GetComponent<ParticleSystem>().Stop();
 0109    _missileExplosionPool.Enqueue(explosion);
 0110    return explosion;
 0111  }
 112
 113  private IEnumerator InstantiateMissileExplosionsOverTime(GameObject prefab, int count,
 0114                                                           float duration) {
 0115    float interval = duration / count;
 0116    for (int i = 0; i < count; ++i) {
 0117      InstantiateMissileExplosion(prefab);
 0118      yield return new WaitForSeconds(interval);
 0119    }
 0120  }
 121
 0122  private void RegisterNewInterceptor(IInterceptor interceptor) {
 0123    interceptor.OnHit += RegisterInterceptorHit;
 0124    interceptor.OnMiss += RegisterInterceptorMiss;
 0125    interceptor.OnTerminated += RegisterAgentTerminated;
 0126  }
 127
 0128  private void RegisterInterceptorHit(IInterceptor interceptor) {
 0129    if (SimManager.Instance.SimulatorConfig.EnableExplosionEffect) {
 0130      PlayMissileExplosion(interceptor.Position);
 0131    }
 0132    GameObject hitMarkerObject = SpawnHitMarker(interceptor.Position);
 0133    hitMarkerObject.GetComponent<UIEventMarker>().SetEventHit();
 0134    _hitMarkerList.Add(hitMarkerObject);
 0135  }
 136
 0137  private void RegisterInterceptorMiss(IInterceptor interceptor) {
 0138    GameObject hitMarkerObject = SpawnHitMarker(interceptor.Position);
 0139    hitMarkerObject.GetComponent<UIEventMarker>().SetEventMiss();
 0140    _hitMarkerList.Add(hitMarkerObject);
 0141  }
 142
 0143  private void RegisterNewThreat(IThreat threat) {
 0144    threat.OnTerminated += RegisterAgentTerminated;
 0145  }
 146
 0147  private void RegisterAgentTerminated(IAgent agent) {
 0148    if (SimManager.Instance.SimulatorConfig.PersistentFlightTrails) {
 0149      CommandeerAgentTrailRenderer(agent);
 0150    }
 0151  }
 152
 0153  private void RegisterSimulationEnded() {
 0154    foreach (var trailRenderer in _agentTrailRenderers) {
 0155      Destroy(trailRenderer.gameObject);
 0156    }
 0157    _agentTrailRenderers.Clear();
 0158  }
 159
 0160  private GameObject SpawnHitMarker(in Vector3 position) {
 0161    GameObject hitMarker =
 162        Instantiate(Resources.Load<GameObject>("Prefabs/HitMarker"), position, Quaternion.identity);
 0163    _hitMarkerList.Add(hitMarker);
 0164    return hitMarker;
 0165  }
 166
 0167  private GameObject PlayMissileExplosion(in Vector3 position) {
 0168    if (_missileExplosionPool.Count > 0) {
 0169      GameObject explosion = _missileExplosionPool.Dequeue();
 0170      explosion.transform.position = position;
 171
 0172      ParticleSystem particleSystem = explosion.GetComponent<ParticleSystem>();
 0173      if (particleSystem != null) {
 0174        particleSystem.Clear();
 0175        particleSystem.Play();
 0176        StartCoroutine(ReturnExplosionAfterDelay(explosion, particleSystem.main.duration));
 0177      } else {
 0178        Debug.LogError("Missile explosion particle has no ParticleSystem component.");
 0179        _missileExplosionPool.Enqueue(explosion);
 0180        return null;
 181      }
 182
 0183      return explosion;
 184    }
 0185    return null;
 0186  }
 187
 0188  private IEnumerator ReturnExplosionAfterDelay(GameObject explosion, float delay) {
 0189    yield return new WaitForSeconds(delay);
 0190    ReturnMissileExplosionParticle(explosion);
 0191  }
 192
 0193  private void ReturnMissileExplosionParticle(GameObject explosion) {
 0194    if (explosion == null) {
 0195      Debug.LogError("Attempted to return a null missile explosion particle.");
 0196      return;
 197    }
 198
 0199    explosion.transform.parent = transform;
 0200    explosion.transform.localPosition = Vector3.zero;
 0201    ParticleSystem particleSystem = explosion.GetComponent<ParticleSystem>();
 0202    if (particleSystem != null) {
 0203      particleSystem.Stop();
 0204      particleSystem.Clear();
 0205    } else {
 0206      Debug.LogError("Attempted to return a missile explosion particle with no particle system.");
 0207    }
 208
 0209    _missileExplosionPool.Enqueue(explosion);
 0210  }
 211
 0212  private void CommandeerAgentTrailRenderer(IAgent agent) {
 213    // Take the TrailRenderer component off of the agent, so it can be destroyed at the end of the
 214    // simulation.
 0215    TrailRenderer trailRenderer = agent.gameObject.GetComponentInChildren<TrailRenderer>();
 0216    if (trailRenderer != null) {
 0217      trailRenderer.transform.parent = transform;
 0218      _agentTrailRenderers.Add(trailRenderer);
 0219      trailRenderer.material = (agent is IThreat) ? ThreatTrailMatFaded : InterceptorTrailMatFaded;
 0220    } else {
 0221      Debug.LogWarning("Agent has no TrailRenderer component.");
 0222    }
 0223  }
 224}