TurbulenceParticleAffector.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. 
  2. // =================================
  3. // Namespaces.
  4. // =================================
  5. using UnityEngine;
  6. // =================================
  7. // Define namespace.
  8. // =================================
  9. namespace MirzaBeig
  10. {
  11. namespace Scripting
  12. {
  13. namespace Effects
  14. {
  15. // =================================
  16. // Classes.
  17. // =================================
  18. public class TurbulenceParticleAffector : ParticleAffector
  19. {
  20. // =================================
  21. // Nested classes and structures.
  22. // =================================
  23. // ...
  24. public enum NoiseType
  25. {
  26. PseudoPerlin,
  27. Perlin,
  28. Simplex,
  29. OctavePerlin,
  30. OctaveSimplex
  31. }
  32. // =================================
  33. // Variables.
  34. // =================================
  35. // ...
  36. [Header("Affector Controls")]
  37. public float speed = 1.0f;
  38. [Range(0.0f, 8.0f)]
  39. public float frequency = 1.0f;
  40. public NoiseType noiseType = NoiseType.Perlin;
  41. // ...
  42. [Header("Octave Variant-Only Controls")]
  43. [Range(1, 8)]
  44. public int octaves = 1;
  45. [Range(0.0f, 4.0f)]
  46. public float lacunarity = 2.0f;
  47. [Range(0.0f, 1.0f)]
  48. public float persistence = 0.5f;
  49. float time;
  50. // Noise start offsets.
  51. float randomX;
  52. float randomY;
  53. float randomZ;
  54. // Final offset.
  55. float offsetX;
  56. float offsetY;
  57. float offsetZ;
  58. // =================================
  59. // Functions.
  60. // =================================
  61. // ...
  62. protected override void Awake()
  63. {
  64. base.Awake();
  65. }
  66. // ...
  67. protected override void Start()
  68. {
  69. base.Start();
  70. // ...
  71. randomX = Random.Range(-32.0f, 32.0f);
  72. randomY = Random.Range(-32.0f, 32.0f);
  73. randomZ = Random.Range(-32.0f, 32.0f);
  74. }
  75. // ...
  76. protected override void Update()
  77. {
  78. time = Time.time;
  79. // ...
  80. base.Update();
  81. }
  82. // ...
  83. protected override void LateUpdate()
  84. {
  85. offsetX = (time * speed) + randomX;
  86. offsetY = (time * speed) + randomY;
  87. offsetZ = (time * speed) + randomZ;
  88. // ...
  89. base.LateUpdate();
  90. }
  91. // ...
  92. protected override Vector3 GetForce()
  93. {
  94. // I could also pre-multiply the frequency, but
  95. // all the octave variants also use frequency
  96. // within themselves, so it would cause redundant
  97. // multiplication.
  98. float xX = parameters.particlePosition.x + offsetX;
  99. float yX = parameters.particlePosition.y + offsetX;
  100. float zX = parameters.particlePosition.z + offsetX;
  101. float xY = parameters.particlePosition.x + offsetY;
  102. float yY = parameters.particlePosition.y + offsetY;
  103. float zY = parameters.particlePosition.z + offsetY;
  104. float xZ = parameters.particlePosition.x + offsetZ;
  105. float yZ = parameters.particlePosition.y + offsetZ;
  106. float zZ = parameters.particlePosition.z + offsetZ;
  107. Vector3 force;
  108. switch (noiseType)
  109. {
  110. case NoiseType.PseudoPerlin:
  111. {
  112. // This isn't really right, but... it gives believable-enough results.
  113. // It's also much faster than real perlin noise.
  114. // It works well where you don't have to animate a large field where
  115. // the repeating pattern would otherwise be easily seen.
  116. // Examples of good uses: smoke trail particle turbulence.
  117. // Example of bad uses: particle box simulating waves or something...
  118. float noiseX = Mathf.PerlinNoise(xX * frequency, yY * frequency);
  119. float noiseY = Mathf.PerlinNoise(xX * frequency, zY * frequency);
  120. float noiseZ = Mathf.PerlinNoise(xX * frequency, xY * frequency);
  121. noiseX = Mathf.Lerp(-1.0f, 1.0f, noiseX);
  122. noiseY = Mathf.Lerp(-1.0f, 1.0f, noiseY);
  123. noiseZ = Mathf.Lerp(-1.0f, 1.0f, noiseZ);
  124. Vector3 forceX = (Vector3.right * noiseX);
  125. Vector3 forceY = (Vector3.up * noiseY);
  126. Vector3 forceZ = (Vector3.forward * noiseZ);
  127. force = forceX + forceY + forceZ;
  128. break;
  129. }
  130. // ...
  131. default:
  132. case NoiseType.Perlin:
  133. {
  134. force.x = Noise.perlin(xX * frequency, yX * frequency, zX * frequency);
  135. force.y = Noise.perlin(xY * frequency, yY * frequency, zY * frequency);
  136. force.z = Noise.perlin(xZ * frequency, yZ * frequency, zZ * frequency);
  137. return force;
  138. }
  139. // ...
  140. case NoiseType.Simplex:
  141. {
  142. force.x = Noise.simplex(xX * frequency, yX * frequency, zX * frequency);
  143. force.y = Noise.simplex(xY * frequency, yY * frequency, zY * frequency);
  144. force.z = Noise.simplex(xZ * frequency, yZ * frequency, zZ * frequency);
  145. break;
  146. }
  147. // ...
  148. case NoiseType.OctavePerlin:
  149. {
  150. force.x = Noise.octavePerlin(xX, yX, zX, frequency, octaves, lacunarity, persistence);
  151. force.y = Noise.octavePerlin(xY, yY, zY, frequency, octaves, lacunarity, persistence);
  152. force.z = Noise.octavePerlin(xZ, yZ, zZ, frequency, octaves, lacunarity, persistence);
  153. break;
  154. }
  155. case NoiseType.OctaveSimplex:
  156. {
  157. force.x = Noise.octaveSimplex(xX, yX, zX, frequency, octaves, lacunarity, persistence);
  158. force.y = Noise.octaveSimplex(xY, yY, zY, frequency, octaves, lacunarity, persistence);
  159. force.z = Noise.octaveSimplex(xZ, yZ, zZ, frequency, octaves, lacunarity, persistence);
  160. break;
  161. }
  162. }
  163. return force;
  164. }
  165. // ...
  166. protected override void OnDrawGizmosSelected()
  167. {
  168. if (enabled)
  169. {
  170. base.OnDrawGizmosSelected();
  171. }
  172. }
  173. // =================================
  174. // End functions.
  175. // =================================
  176. }
  177. // =================================
  178. // End namespace.
  179. // =================================
  180. }
  181. }
  182. }
  183. // =================================
  184. // --END-- //
  185. // =================================