Last active
October 1, 2023 08:12
-
-
Save ditzel/11fdf652a1ce467dadb53e499c381794 to your computer and use it in GitHub Desktop.
Camera Shake Effect. Just put in on the camera and call Shake()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace DitzeGames.Effects | |
{ | |
/// <summary> | |
/// Camera Effects | |
/// </summary> | |
public class CameraEffects : MonoBehaviour | |
{ | |
/// <summary> | |
/// Amount of Shake | |
/// </summary> | |
public Vector3 Amount = new Vector3(1f, 1f, 0); | |
/// <summary> | |
/// Duration of Shake | |
/// </summary> | |
public float Duration = 1; | |
/// <summary> | |
/// Shake Speed | |
/// </summary> | |
public float Speed = 10; | |
/// <summary> | |
/// Amount over Lifetime [0,1] | |
/// </summary> | |
public AnimationCurve Curve = AnimationCurve.EaseInOut(0, 1, 1, 0); | |
/// <summary> | |
/// Set it to true: The camera position is set in reference to the old position of the camera | |
/// Set it to false: The camera position is set in absolute values or is fixed to an object | |
/// </summary> | |
public bool DeltaMovement = true; | |
protected Camera Camera; | |
protected float time = 0; | |
protected Vector3 lastPos; | |
protected Vector3 nextPos; | |
protected float lastFoV; | |
protected float nextFoV; | |
protected bool destroyAfterPlay; | |
/// <summary> | |
/// awake | |
/// </summary> | |
private void Awake() | |
{ | |
Camera = GetComponent<Camera>(); | |
} | |
/// <summary> | |
/// Do the shake | |
/// </summary> | |
public static void ShakeOnce(float duration = 1f, float speed = 10f, Vector3? amount = null, Camera camera = null, bool deltaMovement = true, AnimationCurve curve = null) | |
{ | |
//set data | |
var instance = ((camera != null) ? camera : Camera.main).gameObject.AddComponent<CameraEffects>(); | |
instance.Duration = duration; | |
instance.Speed = speed; | |
if (amount != null) | |
instance.Amount = (Vector3)amount; | |
if (curve != null) | |
instance.Curve = curve; | |
instance.DeltaMovement = deltaMovement; | |
//one time | |
instance.destroyAfterPlay = true; | |
instance.Shake(); | |
} | |
/// <summary> | |
/// Do the shake | |
/// </summary> | |
public void Shake() | |
{ | |
ResetCam(); | |
time = Duration; | |
} | |
private void LateUpdate() | |
{ | |
if (time > 0) | |
{ | |
//do something | |
time -= Time.deltaTime; | |
if (time > 0) | |
{ | |
//next position based on perlin noise | |
nextPos = (Mathf.PerlinNoise(time * Speed, time * Speed * 2) - 0.5f) * Amount.x * transform.right * Curve.Evaluate(1f - time / Duration) + | |
(Mathf.PerlinNoise(time * Speed * 2, time * Speed) - 0.5f) * Amount.y * transform.up * Curve.Evaluate(1f - time / Duration); | |
nextFoV = (Mathf.PerlinNoise(time * Speed * 2, time * Speed * 2) - 0.5f) * Amount.z * Curve.Evaluate(1f - time / Duration); | |
Camera.fieldOfView += (nextFoV - lastFoV); | |
Camera.transform.Translate(DeltaMovement ? (nextPos - lastPos) : nextPos); | |
lastPos = nextPos; | |
lastFoV = nextFoV; | |
} | |
else | |
{ | |
//last frame | |
ResetCam(); | |
if (destroyAfterPlay) | |
Destroy(this); | |
} | |
} | |
} | |
private void ResetCam() | |
{ | |
//reset the last delta | |
Camera.transform.Translate(DeltaMovement ? -lastPos : Vector3.zero); | |
Camera.fieldOfView -= lastFoV; | |
//clear values | |
lastPos = nextPos = Vector3.zero; | |
lastFoV = nextFoV = 0f; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yeah, it did. Thanks so much for that, and just teaching me this much about gamedev in general,