CinemachineBasicMultiChannelPerlin.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using UnityEngine;
  2. using UnityEngine.Serialization;
  3. namespace Cinemachine
  4. {
  5. /// <summary>
  6. /// As a part of the Cinemachine Pipeline implementing the Noise stage, this
  7. /// component adds Perlin Noise to the Camera state, in the Correction
  8. /// channel of the CameraState.
  9. ///
  10. /// The noise is created by using a predefined noise profile asset. This defines the
  11. /// shape of the noise over time. You can scale this in amplitude or in time, to produce
  12. /// a large family of different noises using the same profile.
  13. /// </summary>
  14. /// <seealso cref="NoiseSettings"/>
  15. [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
  16. [AddComponentMenu("")] // Don't display in add component menu
  17. [SaveDuringPlay]
  18. public class CinemachineBasicMultiChannelPerlin : CinemachineComponentBase
  19. {
  20. /// <summary>
  21. /// Serialized property for referencing a NoiseSettings asset
  22. /// </summary>
  23. [Tooltip("The asset containing the Noise Profile. Define the frequencies and amplitudes "
  24. + "there to make a characteristic noise profile. Make your own or just use one of the many presets.")]
  25. [FormerlySerializedAs("m_Definition")]
  26. [NoiseSettingsProperty]
  27. public NoiseSettings m_NoiseProfile;
  28. /// <summary>
  29. /// When rotating the camera, offset the camera's pivot position by this much (camera space)
  30. /// </summary>
  31. [Tooltip("When rotating the camera, offset the camera's pivot position by this much (camera space)")]
  32. public Vector3 m_PivotOffset = Vector3.zero;
  33. /// <summary>
  34. /// Gain to apply to the amplitudes defined in the settings asset.
  35. /// </summary>
  36. [Tooltip("Gain to apply to the amplitudes defined in the NoiseSettings asset. 1 is normal. "
  37. + "Setting this to 0 completely mutes the noise.")]
  38. public float m_AmplitudeGain = 1f;
  39. /// <summary>
  40. /// Scale factor to apply to the frequencies defined in the settings asset.
  41. /// </summary>
  42. [Tooltip("Scale factor to apply to the frequencies defined in the NoiseSettings asset. 1 is normal. "
  43. + "Larger magnitudes will make the noise shake more rapidly.")]
  44. public float m_FrequencyGain = 1f;
  45. /// <summary>True if the component is valid, i.e. it has a noise definition and is enabled.</summary>
  46. public override bool IsValid { get { return enabled && m_NoiseProfile != null; } }
  47. /// <summary>Get the Cinemachine Pipeline stage that this component implements.
  48. /// Always returns the Noise stage</summary>
  49. public override CinemachineCore.Stage Stage { get { return CinemachineCore.Stage.Noise; } }
  50. /// <summary>Applies noise to the Correction channel of the CameraState if the
  51. /// delta time is greater than 0. Otherwise, does nothing.</summary>
  52. /// <param name="curState">The current camera state</param>
  53. /// <param name="deltaTime">How much to advance the perlin noise generator.
  54. /// Noise is only applied if this value is greater than or equal to 0</param>
  55. public override void MutateCameraState(ref CameraState curState, float deltaTime)
  56. {
  57. if (!IsValid || deltaTime < 0)
  58. {
  59. mInitialized = false;
  60. return;
  61. }
  62. if (!mInitialized)
  63. Initialize();
  64. if (TargetPositionCache.CacheMode == TargetPositionCache.Mode.Playback
  65. && TargetPositionCache.HasHurrentTime)
  66. mNoiseTime = TargetPositionCache.CurrentTime * m_FrequencyGain;
  67. else
  68. mNoiseTime += deltaTime * m_FrequencyGain;
  69. curState.PositionCorrection += curState.CorrectedOrientation * NoiseSettings.GetCombinedFilterResults(
  70. m_NoiseProfile.PositionNoise, mNoiseTime, mNoiseOffsets) * m_AmplitudeGain;
  71. Quaternion rotNoise = Quaternion.Euler(NoiseSettings.GetCombinedFilterResults(
  72. m_NoiseProfile.OrientationNoise, mNoiseTime, mNoiseOffsets) * m_AmplitudeGain);
  73. if (m_PivotOffset != Vector3.zero)
  74. {
  75. Matrix4x4 m = Matrix4x4.Translate(-m_PivotOffset);
  76. m = Matrix4x4.Rotate(rotNoise) * m;
  77. m = Matrix4x4.Translate(m_PivotOffset) * m;
  78. curState.PositionCorrection += curState.CorrectedOrientation * m.MultiplyPoint(Vector3.zero);
  79. }
  80. curState.OrientationCorrection = curState.OrientationCorrection * rotNoise;
  81. }
  82. private bool mInitialized = false;
  83. private float mNoiseTime = 0;
  84. [SerializeField][HideInInspector]
  85. private Vector3 mNoiseOffsets = Vector3.zero;
  86. /// <summary>Generate a new random seed</summary>
  87. public void ReSeed()
  88. {
  89. mNoiseOffsets = new Vector3(
  90. Random.Range(-1000f, 1000f),
  91. Random.Range(-1000f, 1000f),
  92. Random.Range(-1000f, 1000f));
  93. }
  94. void Initialize()
  95. {
  96. mInitialized = true;
  97. mNoiseTime = CinemachineCore.CurrentTime * m_FrequencyGain;
  98. if (mNoiseOffsets == Vector3.zero)
  99. ReSeed();
  100. }
  101. }
  102. }