I wrote a camera shake script that you may find useful in your own works.
The Camera Shake is highly versatile/customisable, using perlin noise and exponential falloff for a smooth, realistic feel.
A video description/tutorial can be found below as well as the full commented script (Creative Commons 4.0).
Video
Code
//Created by Arman Awan - ArmanDoesStuff 2018 using System.Collections; using System.Collections.Generic; using UnityEngine; public class CamShake : MonoBehaviour { #region variables public bool camShakeAcive = true; //on or off [Range(0, 1)] [SerializeField] float trauma; [SerializeField] float traumaMult = 16; //the power of the shake [SerializeField] float traumaMag = 0.8f; //the range of movment [SerializeField] float traumaRotMag = 17f; //the rotational power [SerializeField] float traumaDepthMag = 0.6f; //the depth multiplier [SerializeField] float traumaDecay = 1.3f; //how quickly the shake falls off float timeCounter = 0; //counter stored for smooth transition #endregion #region accessors public float Trauma //accessor is used to keep trauma within 0 to 1 range { get { return trauma; } set { trauma = Mathf.Clamp01(value); } } #endregion #region methods //Get a perlin float between -1 & 1, based off the time counter. float GetFloat(float seed) { return (Mathf.PerlinNoise(seed, timeCounter) - 0.5f) * 2f; } //use the above function to generate a Vector3, different seeds are used to ensure different numbers Vector3 GetVec3() { return new Vector3( GetFloat(1), GetFloat(10), //deapth modifier applied here GetFloat(100) * traumaDepthMag ); } private void Update () { if (camShakeAcive && Trauma > 0) { //increase the time counter (how fast the position changes) based off the traumaMult and some root of the Trauma timeCounter += Time.deltaTime * Mathf.Pow(Trauma,0.3f) * traumaMult; //Bind the movement to the desired range Vector3 newPos = GetVec3() * traumaMag * Trauma;; transform.localPosition = newPos; //rotation modifier applied here transform.localRotation = Quaternion.Euler(newPos * traumaRotMag); //decay faster at higher values Trauma -= Time.deltaTime * traumaDecay * (Trauma + 0.3f); } else { //lerp back towards default position and rotation once shake is done Vector3 newPos = Vector3.Lerp(transform.localPosition, Vector3.zero, Time.deltaTime); transform.localPosition = newPos; transform.localRotation = Quaternion.Euler(newPos * traumaRotMag); } } #endregion }
Thanks for reading, I hope you enjoy!