Part of these game systems:
beginner Utilities

Camera Shake

Perlin noise camera shake with magnitude, frequency, and duration. Trigger from explosions, impacts, or any event.

Unity 2022.3+ · 1.8 KB · CameraShake.cs

How to Use

1

Attach CameraShake to your main Camera

2

Call CameraShake.Instance.Shake() from any script

3

Custom intensity: CameraShake.Instance.Shake(0.5f, 0.3f)

4

Subtle hit: Shake(0.15f, 0.05f) | Explosion: Shake(0.6f, 0.5f)

5

Uses Perlin noise for smooth, natural-feeling shake

6

Auto-decays over duration, multiple shakes stack naturally

Source Code

CameraShake.cs
C#
using UnityEngine;

/// <summary>
/// Perlin noise-based camera shake. Attach to your camera.
/// Call Shake() to trigger from any script.
/// </summary>
public class CameraShake : MonoBehaviour
{
    public static CameraShake Instance { get; private set; }

    [Header("Default Settings")]
    [SerializeField] private float defaultDuration = 0.3f;
    [SerializeField] private float defaultMagnitude = 0.15f;
    [SerializeField] private float frequency = 25f;

    private float shakeTimer;
    private float shakeMagnitude;
    private float shakeDuration;
    private Vector3 originalLocalPosition;
    private float seed;

    private void Awake()
    {
        if (Instance == null)
            Instance = this;
        else
        {
            Destroy(this);
            return;
        }

        originalLocalPosition = transform.localPosition;
        seed = Random.value * 1000f;
    }

    private void Update()
    {
        if (shakeTimer <= 0f)
        {
            transform.localPosition = originalLocalPosition;
            return;
        }

        shakeTimer -= Time.unscaledDeltaTime;
        float decay = shakeTimer / shakeDuration;

        float offsetX = (Mathf.PerlinNoise(seed, Time.unscaledTime * frequency) * 2f - 1f) * shakeMagnitude * decay;
        float offsetY = (Mathf.PerlinNoise(seed + 1f, Time.unscaledTime * frequency) * 2f - 1f) * shakeMagnitude * decay;

        transform.localPosition = originalLocalPosition + new Vector3(offsetX, offsetY, 0f);
    }

    /// <summary>
    /// Trigger a camera shake with default settings.
    /// </summary>
    public void Shake()
    {
        Shake(defaultDuration, defaultMagnitude);
    }

    /// <summary>
    /// Trigger a camera shake with custom duration and magnitude.
    /// </summary>
    public void Shake(float duration, float magnitude)
    {
        // Allow stacking: use the stronger shake
        if (shakeTimer > 0f && magnitude <= shakeMagnitude)
            return;

        shakeDuration = duration;
        shakeMagnitude = magnitude;
        shakeTimer = duration;
        seed = Random.value * 1000f;
    }
}