LightEffect.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. using System;
  2. using UnityEngine;
  3. namespace HQFPSWeapons
  4. {
  5. [RequireComponent(typeof(Light))]
  6. public class LightEffect : MonoBehaviour
  7. {
  8. #region Internal
  9. public enum PlayMode { Once, Loop }
  10. [Serializable]
  11. public class PulseSettings
  12. {
  13. public bool Enabled;
  14. public PlayMode Mode;
  15. [Space]
  16. [Range(0f, 3f)]
  17. public float Duration;
  18. public Color Color;
  19. [Space]
  20. [Range(0f, 1f)]
  21. public float IntensityAmplitude;
  22. [Range(0f, 1f)]
  23. public float RangeAmplitude;
  24. [Range(0f, 1f)]
  25. public float ColorWeight;
  26. }
  27. [Serializable]
  28. public class NoiseSettings
  29. {
  30. public bool Enabled;
  31. [Range(0f, 1f)]
  32. public float Intensity = 0.05f;
  33. [Range(0f, 10f)]
  34. public float Speed = 1f;
  35. }
  36. #endregion
  37. public bool IsPlaying { get => m_IsPlaying; }
  38. public float IntensityMultiplier { get; set; }
  39. [SerializeField]
  40. private bool m_PlayOnAwake = false;
  41. [SerializeField]
  42. [Range(0f, 5f)]
  43. private float m_Intensity = 1f;
  44. [SerializeField]
  45. [Range(0f, 10f)]
  46. private float m_Range = 1f;
  47. [SerializeField]
  48. private Color m_Color = Color.yellow;
  49. [Space]
  50. [SerializeField]
  51. [Range(0f, 2f)]
  52. private float m_FadeInTime = 0.5f;
  53. [SerializeField]
  54. [Range(0f, 2f)]
  55. private float m_FadeOutTime = 0.5f;
  56. [Header("Effects")]
  57. [SerializeField]
  58. private PulseSettings m_Pulse = null;
  59. [SerializeField]
  60. private NoiseSettings m_Noise = null;
  61. private bool m_IsPlaying;
  62. private bool m_LightsEnabled;
  63. private float m_Weight;
  64. private bool m_FadingIn;
  65. private bool m_FadingOut;
  66. private Light[] m_Lights;
  67. private bool m_PulseActive;
  68. private float m_PulseTimer;
  69. public void Play(bool fadeIn)
  70. {
  71. if(m_IsPlaying)
  72. return;
  73. m_IsPlaying = true;
  74. m_PulseActive = true;
  75. m_FadingIn = fadeIn;
  76. m_Weight = m_FadingIn ? 0f : 1f;
  77. m_PulseTimer = 0f;
  78. }
  79. public void Stop(bool fadeOut)
  80. {
  81. m_IsPlaying = false;
  82. m_FadingOut = fadeOut;
  83. m_PulseActive = false;
  84. if(!m_FadingOut)
  85. m_Weight = 0f;
  86. }
  87. private void Awake()
  88. {
  89. m_Lights = GetComponentsInChildren<Light>(true);
  90. EnableLights(false);
  91. IntensityMultiplier = 1f;
  92. if (m_PlayOnAwake)
  93. Play(true);
  94. }
  95. private void Update()
  96. {
  97. float intensity = m_Intensity;
  98. float range = m_Range;
  99. Color color = m_Color;
  100. if(m_IsPlaying)
  101. {
  102. // Pulse handling
  103. if (m_Pulse.Enabled && m_PulseActive)
  104. {
  105. float time = m_PulseTimer / Mathf.Max(m_Pulse.Duration, 0.001f);
  106. float param = (Mathf.Sin(Mathf.PI * (2f * time - 0.5f)) + 1f) * 0.5f;
  107. intensity += m_Intensity * param * m_Pulse.IntensityAmplitude;
  108. range += m_Range * param * m_Pulse.RangeAmplitude;
  109. color = Color.Lerp(color, m_Pulse.Color, param * m_Pulse.ColorWeight);
  110. m_PulseTimer += Time.deltaTime;
  111. if(m_PulseTimer > m_Pulse.Duration)
  112. {
  113. if(m_Pulse.Mode == PlayMode.Once)
  114. m_PulseActive = false;
  115. m_PulseTimer = 0f;
  116. }
  117. }
  118. // Auto stop when all effects finished playing
  119. if(!m_PulseActive)
  120. {
  121. m_IsPlaying = false;
  122. m_FadingOut = true;
  123. }
  124. }
  125. // Noise
  126. if(m_LightsEnabled && m_Noise.Enabled)
  127. {
  128. float noise = Mathf.PerlinNoise(Time.time * m_Noise.Speed, 0f) * m_Noise.Intensity;
  129. intensity += m_Intensity * noise;
  130. range += m_Range * noise;
  131. }
  132. // Fade in & out
  133. if(m_FadingIn)
  134. {
  135. m_Weight = Mathf.MoveTowards(m_Weight, 1f, Time.deltaTime * (1f / m_FadeInTime));
  136. if(m_Weight == 1f)
  137. m_FadingIn = false;
  138. }
  139. else if(m_FadingOut)
  140. {
  141. m_Weight = Mathf.MoveTowards(m_Weight, 0f, Time.deltaTime * (1f / m_FadeOutTime));
  142. if(m_Weight == 0f)
  143. {
  144. EnableLights(false);
  145. SetLightsIntensity(0f);
  146. m_FadingOut = false;
  147. }
  148. }
  149. // Enable the light if effects started playing
  150. if(!m_LightsEnabled && m_IsPlaying)
  151. EnableLights(true);
  152. // Apply effects to the light
  153. if(m_LightsEnabled)
  154. SetLightsParameters(intensity * IntensityMultiplier * m_Weight, range, color);
  155. }
  156. private void EnableLights(bool enable)
  157. {
  158. for(int i = 0;i < m_Lights.Length;i++)
  159. m_Lights[i].enabled = enable;
  160. m_LightsEnabled = enable;
  161. }
  162. private void SetLightsIntensity(float intensity)
  163. {
  164. for(int i = 0;i < m_Lights.Length;i++)
  165. m_Lights[i].intensity = intensity;
  166. }
  167. private void SetLightsParameters(float intensity, float range, Color color)
  168. {
  169. for(int i = 0;i < m_Lights.Length;i++)
  170. {
  171. m_Lights[i].intensity = intensity;
  172. m_Lights[i].range = range;
  173. m_Lights[i].color = color;
  174. }
  175. }
  176. }
  177. }