AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
LineParticles.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using HoloToolkit.Unity;
5 using UnityEngine;
6 
7 namespace HoloToolkit.Unity.UX
8 {
9  [UseWith(typeof(LineBase))]
11  {
12  const int GlobalMaxParticles = 2048;
13  const float GlobalParticleStartLifetime = 0.5f;
14 
15  [Header("Particle Settings")]
16  public Material LineMaterial;
17  [Range(128, GlobalMaxParticles)]
18  public int MaxParticles = GlobalMaxParticles;
19  [Range(0.001f, 5f)]
20  public float ParticleStartLifetime = GlobalParticleStartLifetime;
21 
22  [Header("Noise settings")]
23  public bool ParticleNoiseOnDisabled = true;
24  public Vector3 NoiseStrength = Vector3.one;
25  public float NoiseFrequency = 1.2f;
26  [Range(1, 10)]
27  public int NoiseOcatives = 3;
28  [Range(-10f, 10f)]
29  public float NoiseSpeed = 1f;
30  [Range(0.01f, 0.5f)]
31  public float LifetimeAfterDisabled = 0.25f;
32  public Gradient DecayGradient;
33 
34  [SerializeField]
35  private ParticleSystem particles;
36  private ParticleSystem.Particle[] mainParticleArray = new ParticleSystem.Particle[GlobalMaxParticles];
37  private ParticleSystemRenderer mainParticleRenderer;
38  private ParticleSystem.NoiseModule mainNoise;
39  private float decayStartTime = 0f;
40 
41  protected void OnEnable()
42  {
43  particles = gameObject.EnsureComponent<ParticleSystem>();
44 
45  mainNoise = particles.noise;
46 
47  ParticleSystem.EmissionModule emission = particles.emission;
48  emission.rateOverTime = new ParticleSystem.MinMaxCurve(0);
49  emission.rateOverDistance = new ParticleSystem.MinMaxCurve(0);
50  emission.enabled = true;
51 
52  ParticleSystem.MainModule main = particles.main;
53  main.loop = false;
54  main.playOnAwake = false;
55  main.maxParticles = Mathf.Min(MaxParticles, GlobalMaxParticles);
56  main.simulationSpace = ParticleSystemSimulationSpace.World;
57 
58  ParticleSystem.ShapeModule shape = particles.shape;
59  shape.enabled = false;
60 
61  mainParticleRenderer = particles.GetComponent<ParticleSystemRenderer>();
62  mainParticleRenderer.sharedMaterial = LineMaterial;
63 
64  // Initialize our particles
65  for (int i = 0; i < mainParticleArray.Length; i++)
66  {
67  ParticleSystem.Particle particle = mainParticleArray[i];
68  particle.startColor = Color.white;
69  particle.startSize = 1f;
70  particle.startLifetime = float.MaxValue;
71  particle.remainingLifetime = float.MaxValue;
72  particle.velocity = Vector3.zero;
73  particle.angularVelocity = 0;
74  mainParticleArray[i] = particle;
75  }
76  }
77 
78  private void OnDisable()
79  {
80  if (mainParticleRenderer != null)
81  {
82  mainParticleRenderer.enabled = false;
83  }
84  }
85 
86  private void Update()
87  {
88  if (!Source.enabled)
89  {
90  mainNoise.enabled = ParticleNoiseOnDisabled;
91  mainNoise.strengthX = NoiseStrength.x;
92  mainNoise.strengthY = NoiseStrength.y;
93  mainNoise.strengthZ = NoiseStrength.z;
94  mainNoise.octaveCount = NoiseOcatives;
95  mainNoise.scrollSpeed = NoiseSpeed;
96  mainNoise.frequency = NoiseFrequency;
97 
98  if (decayStartTime < 0)
99  {
100  decayStartTime = Time.unscaledTime;
101  }
102  }
103  else
104  {
105  mainNoise.enabled = false;
106  decayStartTime = -1;
107  }
108 
109  if (Source.enabled)
110  {
111  for (int i = 0; i < NumLineSteps; i++)
112  {
113  float normalizedDistance = (1f / (NumLineSteps - 1)) * i;
114  ParticleSystem.Particle particle = mainParticleArray[i];
115  particle.position = Source.GetPoint(normalizedDistance);
116  particle.startColor = GetColor(normalizedDistance);
117  particle.startSize = GetWidth(normalizedDistance);
118  mainParticleArray[i] = particle;
119  }
120  }
121  else
122  {
123  int numDecayingParticles = particles.GetParticles(mainParticleArray);
124  for (int i = 0; i < numDecayingParticles; i++)
125  {
126  float normalizedDistance = (1f / (NumLineSteps - 1)) * i;
127  mainParticleArray[i].startColor = DecayGradient.Evaluate((Time.unscaledTime - decayStartTime) / LifetimeAfterDisabled) * GetColor(normalizedDistance);
128  }
129  }
130  particles.SetParticles(mainParticleArray, NumLineSteps);
131  }
132  }
133 }