TurbulenceParticleForceField.cs 9.2 KB

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