< Summary

Class:ParticleManager
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Managers/ParticleManager.cs
Covered lines:0
Uncovered lines:170
Coverable lines:170
Total lines:245
Line coverage:0% (0 of 170)
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%
Awake()0%6200%
Start()0%12300%
InitializeMissileTrailParticlePool()0%6200%
InitializeMissileExplosionParticlePool()0%6200%
RegisterSimulationEnded()0%6200%
RegisterNewInterceptor(...)0%2100%
RegisterNewThreat(...)0%2100%
RegisterInterceptorHit(...)0%12300%
RegisterInterceptorMiss(...)0%6200%
RegisterThreatHit(...)0%6200%
RegisterThreatMiss(...)0%6200%
CommandeerAgentTrailRenderer(...)0%20400%
PlayMissileExplosion(...)0%12300%
ReturnExplosionAfterDelay()0%12300%
ReturnMissileExplosionParticle(...)0%12300%
InstantiateMissileTrail(...)0%2100%
InstantiateMissileExplosion(...)0%2100%
InstantiateMissileTrailsOverTime()0%20400%
InstantiateMissileExplosionsOverTime()0%20400%
RequestMissileTrailParticle()0%20400%
ReturnMissileTrailParticle(...)0%12300%

File(s)

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

#LineLine coverage
 1using System.Collections;
 2using System.Collections.Generic;
 3using UnityEngine;
 4using System.Linq;
 5
 6public class ParticleManager : MonoBehaviour {
 07  public static ParticleManager Instance { get; private set; }
 8
 9  [SerializeField]
 10  private Queue<GameObject> _missileTrailPool;
 11  [SerializeField]
 12  private Queue<GameObject> _missileExplosionPool;
 13
 014  private List<TrailRenderer> _agentTrailRenderers = new List<TrailRenderer>();
 15
 16  [SerializeField, Tooltip("The material to use for commandeered interceptor trail renderers")]
 17  public Material interceptorTrailMatFaded;
 18  [SerializeField, Tooltip("The material to use for commandeered threat trail renderers")]
 19  public Material threatTrailMatFaded;
 20
 021  private void Awake() {
 022    if (Instance == null) {
 023      Instance = this;
 024      DontDestroyOnLoad(gameObject);
 025    } else {
 026      Destroy(gameObject);
 027    }
 028  }
 29
 030  private void Start() {
 031    _missileTrailPool = new Queue<GameObject>();
 032    _missileExplosionPool = new Queue<GameObject>();
 33
 034    if (SimManager.Instance.simulatorConfig.enableMissileTrailEffect) {
 035      InitializeMissileTrailParticlePool();
 036    }
 037    if (SimManager.Instance.simulatorConfig.enableExplosionEffect) {
 038      InitializeMissileExplosionParticlePool();
 039    }
 40
 41    // Subscribe to events!
 042    SimManager.Instance.OnNewInterceptor += RegisterNewInterceptor;
 043    SimManager.Instance.OnNewThreat += RegisterNewThreat;
 44
 045    SimManager.Instance.OnSimulationEnded += RegisterSimulationEnded;
 046  }
 47
 048  private void InitializeMissileTrailParticlePool() {
 49    // Grab from Resources/Prefabs/Effects
 050    GameObject missileTrailPrefab =
 51        Resources.Load<GameObject>("Prefabs/Effects/InterceptorSmokeEffect");
 52
 53    // Pre-instantiate 10 missile trail particles
 054    for (int i = 0; i < 10; i++) {
 055      InstantiateMissileTrail(missileTrailPrefab);
 056    }
 57    // Instantiate over an interval
 058    StartCoroutine(InstantiateMissileTrailsOverTime(missileTrailPrefab, 200, 0.05f));
 059  }
 60
 061  private void InitializeMissileExplosionParticlePool() {
 062    GameObject missileExplosionPrefab =
 63        Resources.Load<GameObject>("Prefabs/Effects/InterceptExplosionEffect");
 64    // Pre-instantiate 10 missile trail particles
 065    for (int i = 0; i < 10; i++) {
 066      InstantiateMissileExplosion(missileExplosionPrefab);
 067    }
 068    StartCoroutine(InstantiateMissileExplosionsOverTime(missileExplosionPrefab, 200, 0.05f));
 069  }
 70
 071  private void RegisterSimulationEnded() {
 072    foreach (var trailRenderer in _agentTrailRenderers) {
 073      Destroy(trailRenderer.gameObject);
 074    }
 075    _agentTrailRenderers.Clear();
 076  }
 77
 078  private void RegisterNewInterceptor(Interceptor interceptor) {
 079    interceptor.OnInterceptHit += RegisterInterceptorHit;
 080    interceptor.OnInterceptMiss += RegisterInterceptorMiss;
 081  }
 82
 083  private void RegisterNewThreat(Threat threat) {
 084    threat.OnThreatHit += RegisterThreatHit;
 085    threat.OnThreatMiss += RegisterThreatMiss;
 086  }
 87
 088  private void RegisterInterceptorHit(Interceptor interceptor, Threat threat) {
 089    if (SimManager.Instance.simulatorConfig.enableExplosionEffect) {
 090      PlayMissileExplosion(interceptor.transform.position);
 091    }
 092    if (SimManager.Instance.simulatorConfig.persistentFlightTrails) {
 093      CommandeerAgentTrailRenderer(interceptor);
 094      CommandeerAgentTrailRenderer(threat);
 095    }
 096  }
 97
 098  private void RegisterInterceptorMiss(Interceptor interceptor, Threat threat) {
 099    if (SimManager.Instance.simulatorConfig.persistentFlightTrails) {
 0100      CommandeerAgentTrailRenderer(interceptor);
 0101    }
 0102  }
 103
 0104  private void RegisterThreatHit(Threat threat) {
 0105    if (SimManager.Instance.simulatorConfig.persistentFlightTrails) {
 0106      CommandeerAgentTrailRenderer(threat);
 0107    }
 0108  }
 109
 0110  private void RegisterThreatMiss(Threat threat) {
 0111    if (SimManager.Instance.simulatorConfig.persistentFlightTrails) {
 0112      CommandeerAgentTrailRenderer(threat);
 0113    }
 0114  }
 115
 0116  private void CommandeerAgentTrailRenderer(Agent agent) {
 117    // Take the TrailRenderer component off of the agent, onto us, and store it
 118    // (so we can destroy it later on simulation end)
 0119    TrailRenderer trailRenderer = agent.GetComponentInChildren<TrailRenderer>();
 0120    if (trailRenderer != null) {
 0121      trailRenderer.transform.parent = transform;
 0122      _agentTrailRenderers.Add(trailRenderer);
 0123      trailRenderer.material = (agent is Threat) ? threatTrailMatFaded : interceptorTrailMatFaded;
 0124    } else {
 0125      Debug.LogWarning("Agent has no TrailRenderer component");
 0126    }
 0127  }
 128
 129  /// <summary>
 130  /// Returns a missile explosion particle prefab from the pool and plays it at the specified
 131  /// location. If the pool is empty, it returns null.
 132  /// </summary>
 0133  public GameObject PlayMissileExplosion(Vector3 position) {
 0134    if (_missileExplosionPool.Count > 0) {
 0135      GameObject explosion = _missileExplosionPool.Dequeue();
 0136      explosion.transform.position = position;
 137
 0138      ParticleSystem particleSystem = explosion.GetComponent<ParticleSystem>();
 0139      if (particleSystem != null) {
 0140        particleSystem.Clear();
 0141        particleSystem.Play();
 0142        StartCoroutine(ReturnExplosionAfterDelay(explosion, particleSystem.main.duration));
 0143      } else {
 0144        Debug.LogError("Missile explosion particle has no ParticleSystem component");
 0145        _missileExplosionPool.Enqueue(explosion);
 0146        return null;
 147      }
 148
 0149      return explosion;
 150    }
 0151    return null;
 0152  }
 153
 0154  private IEnumerator ReturnExplosionAfterDelay(GameObject explosion, float delay) {
 0155    yield return new WaitForSeconds(delay);
 0156    ReturnMissileExplosionParticle(explosion);
 0157  }
 158
 0159  private void ReturnMissileExplosionParticle(GameObject explosion) {
 0160    if (explosion == null) {
 0161      Debug.LogError("Attempted to return a null missile explosion particle");
 0162      return;
 163    }
 164
 0165    explosion.transform.parent = transform;
 0166    explosion.transform.localPosition = Vector3.zero;
 0167    ParticleSystem particleSystem = explosion.GetComponent<ParticleSystem>();
 0168    if (particleSystem != null) {
 0169      particleSystem.Stop();
 0170      particleSystem.Clear();
 0171    } else {
 0172      Debug.LogError("Attempted to return a missile explosion particle with no particle system");
 0173    }
 174
 0175    _missileExplosionPool.Enqueue(explosion);
 0176  }
 177
 0178  private GameObject InstantiateMissileTrail(GameObject prefab) {
 0179    GameObject trail = Instantiate(prefab, transform);
 0180    trail.GetComponent<ParticleSystem>().Stop();
 0181    _missileTrailPool.Enqueue(trail);
 0182    return trail;
 0183  }
 184
 0185  private GameObject InstantiateMissileExplosion(GameObject prefab) {
 0186    GameObject explosion = Instantiate(prefab, transform);
 0187    explosion.GetComponent<ParticleSystem>().Stop();
 0188    _missileExplosionPool.Enqueue(explosion);
 0189    return explosion;
 0190  }
 191
 192  private IEnumerator InstantiateMissileTrailsOverTime(GameObject prefab, int count,
 0193                                                       float duration) {
 0194    float interval = duration / count;
 0195    for (int i = 0; i < count; i++) {
 0196      InstantiateMissileTrail(prefab);
 0197      yield return new WaitForSeconds(interval);
 0198    }
 0199  }
 200
 201  private IEnumerator InstantiateMissileExplosionsOverTime(GameObject prefab, int count,
 0202                                                           float duration) {
 0203    float interval = duration / count;
 0204    for (int i = 0; i < count; i++) {
 0205      InstantiateMissileExplosion(prefab);
 0206      yield return new WaitForSeconds(interval);
 0207    }
 0208  }
 209
 210  /// <summary>
 211  /// Returns a missile trail particle prefab from the pool.
 212  /// If the pool is empty, it returns null
 213  /// </summary>
 214  /// <returns></returns>
 0215  public GameObject RequestMissileTrailParticle() {
 0216    if (_missileTrailPool.Count > 0 &&
 0217        SimManager.Instance.simulatorConfig.enableMissileTrailEffect) {
 0218      GameObject trail = _missileTrailPool.Dequeue();
 219
 0220      return trail;
 221    }
 0222    return null;
 0223  }
 224
 0225  public void ReturnMissileTrailParticle(GameObject trail) {
 0226    if (trail == null) {
 0227      Debug.LogError("Attempted to return a null missile trail particle");
 0228      return;
 229    }
 230
 0231    trail.transform.parent = transform;
 0232    trail.transform.localPosition = Vector3.zero;
 0233    ParticleSystem particleSystem = trail.GetComponent<ParticleSystem>();
 0234    if (particleSystem != null) {
 0235      particleSystem.Stop();
 0236      particleSystem.Clear();
 0237      var emission = particleSystem.emission;
 0238      emission.enabled = true;
 0239    } else {
 0240      Debug.LogError("Attempted to return a missile trail particle with no particle system");
 0241    }
 242
 0243    _missileTrailPool.Enqueue(trail);
 0244  }
 245}