using FirstGearGames.Utilities.Objects; using System; using System.Collections.Generic; using UnityEngine; namespace FirstGearGames.SmoothCameraShaker { public class ObjectShakerHandler : MonoBehaviour { #region Public. ///// ///// Dispatched after a Shaker is added to InstantiatedShakers. ///// //public static event Action OnShakerInstantiated; ///// ///// Dispatched after a Shaker is removed from InstantiatedShakers. ///// //public static event Action OnShakerDestroyed; /// /// All instantiatedShaker scripts. /// public static List InstantiatedShakers = new List(); #endregion #region Private. /// /// Collection of Shakers which are currently shaking. /// private List _shaking = new List(); /// /// Singleton instance of this script. /// private static ObjectShakerHandler _instance; #endregion private void Awake() { //Make sure there is only once instance. if (_instance != null && _instance != this) { if (Debug.isDebugBuild) Debug.LogWarning("Multiple ObjectShakerHandler scripts found. This script auto loads itself and does not need to be placed in your scenes."); Destroy(this); return; } } private void Update() { UpdateShakers(); } private void FixedUpdate() { UpdateFixedShakers(); } private void OnDestroy() { DisableAll(); } /// /// Initializes this script for use. Should only be completed once. /// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void FirstInitialize() { DDOL ddol = DDOL.ReturnDDOL(); GameObject obj = new GameObject(); obj.name = "ObjectShakerHandler"; _instance = obj.AddComponent(); _instance.enabled = false; _instance.transform.SetParent(ddol.transform); } /// /// Disables activity on all camera shakers. /// private void DisableAll() { //Disable camera shakers. for (int i = 0; i < InstantiatedShakers.Count; i++) { if (InstantiatedShakers[i] != null) InstantiatedShakers[i].Disable(); } } /// /// Updates Shakers on standard time. /// private void UpdateShakers() { if (_shaking.Count == 0) return; for (int i = 0; i < InstantiatedShakers.Count; i++) InstantiatedShakers[i].UpdateShakers(); } /// /// Updates Shakers on fixed time. /// private void UpdateFixedShakers() { for (int i = 0; i < InstantiatedShakers.Count; i++) InstantiatedShakers[i].UpdateFixedShakers(); } /// /// Returns if an action can be run on the specified Shaker using an All method. /// /// /// /// private static bool CanRunAllOn(ObjectShaker shaker, bool includeDisabled) { if (shaker == null) return false; if (!shaker.gameObject.activeInHierarchy && !includeDisabled) return false; return true; } #region Shaker referencing handling. /// /// Adds Shaker to shaking. This is for internal use only. /// /// internal static void AddShaking(ObjectShaker shaker) { _instance._shaking.AddUnique(shaker); _instance.enabled = (_instance._shaking.Count > 0); } /// /// Removes Shaker from shaking. This is for internal use only. /// /// internal static void RemoveShaking(ObjectShaker shaker) { _instance._shaking.Remove(shaker); _instance.enabled = (_instance._shaking.Count > 0); } /// /// Adds a Shaker to the InstantiatedShakers field. This is for internal use only. /// /// internal static void AddInstantiatedShaker(ObjectShaker value) { InstantiatedShakers.AddUnique(value); //OnShakerInstantiated?.Invoke(value); } /// /// Removes a Shaker from the InstantiatedShakers field. This is for internal use only. /// /// internal static void RemoveInstantiatedShaker(ObjectShaker value) { InstantiatedShakers.Remove(value); //OnShakerDestroyed?.Invoke(value); } #endregion #region API. /// /// Copies ShakerInstances from one CameraShaker to another. /// /// CameraShaker copied from. /// CameraShaker copied to. public static void CopyShakerInstances(ObjectShaker from, ObjectShaker to) { //If neither shaker is null then add instances. if (from != null && to != null) to.AddShakerInstances(from.ShakerInstances); } /// /// Sets the Scale value of InstantiatedCameraShakers. /// /// New scale to use /// True to issue call on disabled CameraShakers as well. public static void SetScaleAll(float value, bool includeDisabled = false) { for (int i = 0; i < InstantiatedShakers.Count; i++) { if (!CanRunAllOn(InstantiatedShakers[i], includeDisabled)) continue; InstantiatedShakers[i].SetScale(value); } } /// /// Shakes the all camera shakers using data. /// /// ShakeData to use. /// True to issue call on disabled CameraShakers as well. /// Instances generated using data. public static List ShakeAll(ShakeData data, bool includeDisabled = false) { List results = new List(); for (int i = 0; i < InstantiatedShakers.Count; i++) { if (!CanRunAllOn(InstantiatedShakers[i], includeDisabled)) continue; results.Add(InstantiatedShakers[i].Shake(data)); } return results; } /// /// Sets the paused state of all shaker instances on the all CameraShakers. /// /// New pause state. /// True to issue call on disabled CameraShakers as well. public static void SetPausedAll(bool value, bool includeDisabled = false) { for (int i = 0; i < InstantiatedShakers.Count; i++) { if (!CanRunAllOn(InstantiatedShakers[i], includeDisabled)) continue; InstantiatedShakers[i].SetPaused(value); } } /// /// Abruptly stops all instances on InstantiatedCameraShakers. /// /// True to issue call on disabled CameraShakers as well. public static void StopAll(bool includeDisabled = false) { for (int i = 0; i < InstantiatedShakers.Count; i++) { if (!CanRunAllOn(InstantiatedShakers[i], includeDisabled)) continue; InstantiatedShakers[i].Stop(); } } /// /// Fades out all instances on all CameraShakers. This operation only works on instances not already fading out. /// /// Overrides instance fade out duration with a new value. /// True to issue call on disabled CameraShakers as well. public static void FadeOutAll(float? durationOverride = null, bool includeDisabled = false) { for (int i = 0; i < InstantiatedShakers.Count; i++) { if (!CanRunAllOn(InstantiatedShakers[i], includeDisabled)) continue; InstantiatedShakers[i].FadeOut(durationOverride); } } /// /// Multiplies magnitude values for all instances on all camera shakers. /// /// Value to multiply by. 1f is standard multiplication, which in result would be default values. /// How quickly per second to move towards new multiplier. Values 0f and lower are instant. /// True to modify move rate based on distance from multiplier. False to move towards goal using movdRate unmodified. /// True to issue call on disabled CameraShakers as well. public void MultiplyMagnitudeAll(float multiplier, float moveRate, bool rateUsesDistance, bool includeDisabled = false) { for (int i = 0; i < InstantiatedShakers.Count; i++) { if (!CanRunAllOn(InstantiatedShakers[i], includeDisabled)) continue; InstantiatedShakers[i].MultiplyMagnitude(multiplier, moveRate, rateUsesDistance); } } /// /// Multiplies roughness values for all instances on all camera shakers. /// /// Value to multiply by. 1f is standard multiplication, which in result would be default values. /// How quickly per second to move towards new multiplier. Values 0f and lower are instant. /// True to modify move rate based on distance from multiplier. False to move towards goal using movdRate unmodified. /// True to issue call on disabled CameraShakers as well. public void MultiplyRoughnessAll(float multiplier, float moveRate, bool rateUsesDistance, bool includeDisabled = false) { for (int i = 0; i < InstantiatedShakers.Count; i++) { if (!CanRunAllOn(InstantiatedShakers[i], includeDisabled)) continue; InstantiatedShakers[i].MultiplyRoughness(multiplier, moveRate, rateUsesDistance); } } #endregion } }