using System.Collections.Generic; using UnityEngine; namespace CameraShake { /// /// Camera shaker component registeres new shakes, holds a list of active shakes, and applies them to the camera additively. /// public class CameraShaker : MonoBehaviour { public static CameraShaker Instance; public static CameraShakePresets Presets; readonly List activeShakes = new List(); [Tooltip("Transform which will be affected by the shakes.\n\nCameraShaker will set this transform's local position and rotation.")] [SerializeField] Transform cameraTransform; [Tooltip("Scales the strength of all shakes.")] [Range(0, 1)] [SerializeField] public float StrengthMultiplier = 1; public CameraShakePresets ShakePresets; /// /// Adds a shake to the list of active shakes. /// public static void Shake(ICameraShake shake) { if (IsInstanceNull()) return; Instance.RegisterShake(shake); } /// /// Adds a shake to the list of active shakes. /// public void RegisterShake(ICameraShake shake) { shake.Initialize(cameraTransform.position, cameraTransform.rotation); activeShakes.Add(shake); } /// /// Sets the transform which will be affected by the shakes. /// public void SetCameraTransform(Transform cameraTransform) { cameraTransform.localPosition = Vector3.zero; cameraTransform.localEulerAngles = Vector3.zero; this.cameraTransform = cameraTransform; } private void Awake() { Instance = this; ShakePresets = new CameraShakePresets(this); Presets = ShakePresets; if (cameraTransform == null) cameraTransform = transform; } public void UpdateShake() { if (cameraTransform == null) return; Displacement cameraDisplacement = Displacement.Zero; for (int i = activeShakes.Count - 1; i >= 0; i--) { if (activeShakes[i].IsFinished) { activeShakes.RemoveAt(i); } else { activeShakes[i].Update(Time.deltaTime, cameraTransform.position, cameraTransform.rotation); cameraDisplacement += activeShakes[i].CurrentDisplacement; } } cameraTransform.localPosition = transform.localPosition + StrengthMultiplier * cameraDisplacement.position; cameraTransform.localRotation *= Quaternion.Euler(StrengthMultiplier * cameraDisplacement.eulerAngles); } private static bool IsInstanceNull() { if (Instance == null) { Debug.LogError("CameraShaker Instance is missing!"); return true; } return false; } } }