Step 1: Create a script called CameraShaker and assign it to your Main camera or any active Game object

CameraShaker.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class CameraShaker : MonoBehaviour
{
    private CinemachineVirtualCamera _virtualCamera;
    private CinemachineBasicMultiChannelPerlin _cameraNoise;

    private const float Strength = 1.0f;

    private void Start()
    {
        _virtualCamera = FindObjectOfType<CinemachineVirtualCamera>();
        if (_virtualCamera != null)
        {
            _cameraNoise = _virtualCamera.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
        }
    }

    #region Normal Shake
    public void NormalShake(float intensity, float duration)
    {
        StopAllCoroutines();
        StartCoroutine(PerformNormalShake(intensity, duration));
    }

    private IEnumerator PerformNormalShake(float intensity, float duration)
    {
        _cameraNoise.m_AmplitudeGain = intensity * Strength;
        yield return new WaitForSeconds(duration);
        _cameraNoise.m_AmplitudeGain = 0;
    }
    #endregion

    #region Smooth Shake
    public void SmoothShake(float intensity, float duration, float fadeInTime = 0, float fadeOutTime = 0)
    {
        StopAllCoroutines();
        StartCoroutine(PerformSmoothShake(intensity, duration, fadeInTime, fadeOutTime));
    }

    private IEnumerator PerformSmoothShake(float intensity, float duration, float fadeInTime, float fadeOutTime)
    {
        float startTime = Time.time;
        _cameraNoise.m_AmplitudeGain = 0;

        // Fade In
        while (Time.time - startTime < fadeInTime)
        {
            float fadeAmount = Mathf.Lerp(0, intensity, (Time.time - startTime) / fadeInTime);
            _cameraNoise.m_AmplitudeGain = fadeAmount * intensity * Strength;
            yield return null;
        }

        // Main Shake
        float shakeStartTime = Time.time;
        while (Time.time - shakeStartTime < duration)
        {
            float t = (Time.time - shakeStartTime) / duration;
            float noise = Mathf.PerlinNoise(t * 10, t * 10);
            _cameraNoise.m_AmplitudeGain = noise * intensity * Strength;
            yield return null;
        }

        // Fade Out
        float fadeOutStartTime = Time.time;
        while (Time.time - fadeOutStartTime < fadeOutTime)
        {
            float fadeAmount = Mathf.Lerp(intensity, 0, (Time.time - fadeOutStartTime) / fadeOutTime);
            _cameraNoise.m_AmplitudeGain = fadeAmount * intensity * Strength;
            yield return null;
        }

        _cameraNoise.m_AmplitudeGain = 0;
    }
    #endregion
}

Step 2: Next select your Cinemachine Camera and Change the Noise to Basic Multi Channel Perlin and Nosie Profile to 6D Wobble or 6D shake

Step3: Finally, Call your method like following:

private CameraShaker _cameraShaker;

        void Start()
        {
            Debug.Log("PlayerHitDeath script is attached to: " + gameObject.name);
            playerAnimator = GetComponent<PlayerAnimator>();
            // find by tag
            _cameraShaker = FindObjectOfType<CameraShaker>();
        }
      

_cameraShaker.SmoothShake(2f, 5f);



By simply passing the intensity, strength and fade duration as arguments

Here is Example implementation of mine: This camera shake was called when our player collides with our Box

using Cinemachine;
using UnityEngine;

    public class PlayerHitDeath : MonoBehaviour
    {
        [SerializeField] private float weightThreshold = 50f; // Set the weight threshold
        [SerializeField] private Animator animator; // Reference to the player's animator
        [SerializeField] private float velocityThreshold;
        [SerializeField] private PlayerAnimator playerAnimator;
        // cinemachine camera
        private CameraShaker _cameraShaker;

        void Start()
        {
            playerAnimator = GetComponent<PlayerAnimator>();
            // find by tag
            _cameraShaker = FindObjectOfType<CameraShaker>();
        }
        Rigidbody2D rb;
        private void OnCollisionEnter2D(Collision2D collision)
        {
            if (collision.collider != null)
            {
                rb = collision.collider.GetComponent<Rigidbody2D>();
                if (rb != null)
                {
                    // check if the rb tag is "Box" and Debug.Log the velocity magnitude
                    if (collision.collider.CompareTag("Box"))
                    {
                        Debug.Log("Box's magnitude: " + rb.velocity.magnitude);
                        // Debug.Log the box's mass
                        Debug.Log("Box's mass: " + rb.mass);

                        // Check if the box is falling on the player
                        float shakeIntensity = Mathf.Clamp(rb.velocity.x, 0, 20); // Set the maximum shake intensity
                        Debug.Log("Shake intensity: " + shakeIntensity);

                        float collisionDuration = collision.relativeVelocity.magnitude / 10;
                        _cameraShaker.SmoothShake(2f, collisionDuration);
                        Debug.Log("shook the camera");
                        if (rb.velocity.y < 0)
                        {
                            Debug.Log("Box is falling on the player");
                            if (rb.velocity.magnitude > velocityThreshold)
                            {

                            }
                        }
                    }
                    Debug.Log("rb.velocity.magnitude: " + rb.velocity.magnitude);
                }
            }
        }
    }

Discover more from TheFlipbit

Subscribe to get the latest posts to your email.

Leave a Reply

Discover more from TheFlipbit

Subscribe now to keep reading and get access to the full archive.

Continue reading