NoiseSettings.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using UnityEngine;
  2. using System;
  3. using UnityEngine.Serialization;
  4. namespace Cinemachine
  5. {
  6. /// <summary>
  7. /// This is an asset that defines a noise profile. A noise profile is the
  8. /// shape of the noise signal as a function of time. You can build arbitrarily complex shapes by
  9. /// combining different base perlin noise frequencies at different amplitudes.
  10. ///
  11. /// The frequencies and amplitudes should be chosen with care, to ensure an interesting
  12. /// noise quality that is not obviously repetitive.
  13. ///
  14. /// As a mathematical side-note, any arbitrary periodic curve can be broken down into a
  15. /// series of fixed-amplitude sine-waves added together. This is called fourier decomposition,
  16. /// and is the basis of much signal processing. It doesn't really have much to do with this
  17. /// asset, but it's super interesting!
  18. /// </summary>
  19. [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
  20. [HelpURL(Documentation.BaseURL + "manual/CinemachineNoiseProfiles.html")]
  21. public sealed class NoiseSettings : SignalSourceAsset
  22. {
  23. /// <summary>Describes the behaviour for a channel of noise</summary>
  24. [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
  25. [Serializable]
  26. public struct NoiseParams
  27. {
  28. /// <summary>The frequency of noise for this channel. Higher magnitudes vibrate faster</summary>
  29. [Tooltip("The frequency of noise for this channel. Higher magnitudes vibrate faster.")]
  30. public float Frequency;
  31. /// <summary>The amplitude of the noise for this channel. Larger numbers vibrate higher</summary>
  32. [Tooltip("The amplitude of the noise for this channel. Larger numbers vibrate higher.")]
  33. public float Amplitude;
  34. /// <summary>If checked, then the amplitude and frequency will not be randomized</summary>
  35. [Tooltip("If checked, then the amplitude and frequency will not be randomized.")]
  36. public bool Constant;
  37. /// <summary>Get the signal value at a given time, offset by a given amount</summary>
  38. public float GetValueAt(float time, float timeOffset)
  39. {
  40. float t = (Frequency * time) + timeOffset;
  41. if (Constant)
  42. return Mathf.Cos(t * 2 * Mathf.PI) * Amplitude * 0.5f;
  43. return (Mathf.PerlinNoise(t, 0f) - 0.5f) * Amplitude;
  44. }
  45. }
  46. /// <summary>
  47. /// Contains the behaviour of noise for the noise module for all 3 cardinal axes of the camera
  48. /// </summary>
  49. [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
  50. [Serializable]
  51. public struct TransformNoiseParams
  52. {
  53. /// <summary>Noise definition for X-axis</summary>
  54. [Tooltip("Noise definition for X-axis")]
  55. public NoiseParams X;
  56. /// <summary>Noise definition for Y-axis</summary>
  57. [Tooltip("Noise definition for Y-axis")]
  58. public NoiseParams Y;
  59. /// <summary>Noise definition for Z-axis</summary>
  60. [Tooltip("Noise definition for Z-axis")]
  61. public NoiseParams Z;
  62. /// <summary>Get the signal value at a given time, offset by a given amount</summary>
  63. public Vector3 GetValueAt(float time, Vector3 timeOffsets)
  64. {
  65. return new Vector3(
  66. X.GetValueAt(time, timeOffsets.x),
  67. Y.GetValueAt(time, timeOffsets.y),
  68. Z.GetValueAt(time, timeOffsets.z));
  69. }
  70. }
  71. /// <summary>The array of positional noise channels for this <c>NoiseSettings</c></summary>
  72. [Tooltip("These are the noise channels for the virtual camera's position. Convincing noise setups typically mix low, medium and high frequencies together, so start with a size of 3")]
  73. [FormerlySerializedAs("m_Position")]
  74. public TransformNoiseParams[] PositionNoise = new TransformNoiseParams[0];
  75. /// <summary>The array of orientation noise channels for this <c>NoiseSettings</c></summary>
  76. [Tooltip("These are the noise channels for the virtual camera's orientation. Convincing noise setups typically mix low, medium and high frequencies together, so start with a size of 3")]
  77. [FormerlySerializedAs("m_Orientation")]
  78. public TransformNoiseParams[] OrientationNoise = new TransformNoiseParams[0];
  79. /// <summary>Get the noise signal value at a specific time</summary>
  80. /// <param name="noiseParams">The parameters that define the noise function</param>
  81. /// <param name="time">The time at which to sample the noise function</param>
  82. /// <param name="timeOffsets">Start time offset for each channel</param>
  83. /// <returns>The 3-channel noise signal value at the specified time</returns>
  84. public static Vector3 GetCombinedFilterResults(
  85. TransformNoiseParams[] noiseParams, float time, Vector3 timeOffsets)
  86. {
  87. Vector3 pos = Vector3.zero;
  88. if (noiseParams != null)
  89. {
  90. for (int i = 0; i < noiseParams.Length; ++i)
  91. pos += noiseParams[i].GetValueAt(time, timeOffsets);
  92. }
  93. return pos;
  94. }
  95. /// <summary>
  96. /// Returns the total length in seconds of the signal.
  97. /// Returns 0 for signals of indeterminate length.
  98. /// </summary>
  99. public override float SignalDuration { get { return 0; } }
  100. /// <summary>Interface for raw signal provider</summary>
  101. /// <param name="pos">The position impulse signal</param>
  102. /// <param name="rot">The rotation impulse signal</param>
  103. public override void GetSignal(float timeSinceSignalStart, out Vector3 pos, out Quaternion rot)
  104. {
  105. pos = GetCombinedFilterResults(PositionNoise, timeSinceSignalStart, Vector3.zero);
  106. rot = Quaternion.Euler(GetCombinedFilterResults(OrientationNoise, timeSinceSignalStart, Vector3.zero));
  107. }
  108. }
  109. }