object (esp. camera) shake

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// put this on any object (especially cameras) to call shake function
// how far it shakes, how long it shakes, how rapidly it shakes
// eg. DoShake(new Vector3(.25f, .25f, .25f), .25f, .25f);
// 
// if you want to move the shaking object, parent it to an empty pivot
// move the parent, shake the child
public class ObjectShaker : MonoBehaviour {
    private float endTime;
    
    public void DoShake(Vector3 magnitude, float duration, float wavelength) {
        bool start = endTime < Time.time;
        endTime = Time.time + duration;
        
        if (start) {
            StartCoroutine(ShakeCoroutine(magnitude, wavelength));
        }
    }
    
    private IEnumerator ShakeCoroutine(Vector3 magnitude, float wavelength) {
        Vector3 startPos = transform.localPosition;
        float currentX = 0;
        
        // different coordinates for different axes
        float xCoord = Random.value * 5;
        float yCoord = Random.value * 5 + 5;
        float zCoord = Random.value * 5 + 10;
        
        while (Time.time <= endTime) {
            Vector3 shakeAmount = new Vector3(
                Mathf.PerlinNoise(currentX, xCoord) - .5f,
                Mathf.PerlinNoise(currentX, yCoord) - .5f,
                Mathf.PerlinNoise(currentX, zCoord) - .5f
            );
            
            transform.localPosition = Vector3.Scale(magnitude, shakeAmount) + startPos;
            currentX += 10 * Time.deltaTime / wavelength;
            yield return null;
        }
        
        transform.localPosition = startPos;
    }
}