Introduction
When it comes to adding that extra oomph to your Unity game, nothing sells impact quite like a good camera shake. Whether it's a massive explosion, an intense earthquake, or a hard-hitting punch, shaking the camera enhances immersion and makes the player feel the action.
In this post, we'll break down a simple yet powerful Cinemachine Camera Shake system that you can easily integrate into your Unity project.
Why Use Cinemachine for Camera Shake?
Unity's Cinemachine is an amazing tool for handling in-game cameras. It gives you smooth transitions, dolly zooms, and best of all, built-in noise settings that make implementing camera shake a breeze.
Instead of manually modifying the camera's position or writing complex per-frame adjustments, CinemachineBasicMultiChannelPerlin does the heavy lifting by introducing procedural noise.
The Code: Cinemachine Camera Shake in Action
Here's a complete script to implement a dynamic camera shake in Unity using Cinemachine.
using System.Collections;
using Cinemachine;
using UnityEngine;
public class CinemachineShake : MonoBehaviour
{
public static CinemachineShake cinemachineShake; // Singleton for easy access
[SerializeField] private AnimationCurve animationCurve;
[SerializeField] private float shakeIntensity;
public CinemachineVirtualCamera cinemachineCamera;
private CinemachineBasicMultiChannelPerlin noise;
private bool isShaking = false;
private void Awake()
{
if (cinemachineShake == null)
{
cinemachineShake = this;
noise = cinemachineCamera.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
}
else
{
Destroy(gameObject);
}
}
// Call this method to trigger the camera shake effect
public void StartShakeCamera(float duration)
{
StartCoroutine(ShakeCamera(duration));
}
private IEnumerator ShakeCamera(float duration)
{
if (isShaking) yield break;
float elapsedTime = 0f;
isShaking = true;
while (elapsedTime < duration)
{
elapsedTime += Time.deltaTime;
float strength = animationCurve.Evaluate(elapsedTime / duration);
noise.m_AmplitudeGain = shakeIntensity * strength;
yield return null;
}
noise.m_AmplitudeGain = 0f;
isShaking = false;
}
}
Breaking Down the Code
Singleton Pattern
- The script uses a Singleton (
cinemachineShake) to provide easy access from other scripts.
Cinemachine Setup
- A CinemachineVirtualCamera is assigned in the Inspector, and the CinemachineBasicMultiChannelPerlin component is used for the shake effect.
Shake Logic
- The camera shake effect is triggered using
StartShakeCamera(float duration), which starts a coroutine to animate the shake over time. - An AnimationCurve controls the intensity, allowing for smooth fading in and out.
- The noise.m_AmplitudeGain property determines the shake strength.
Preventing Overlapping Shakes
- The
isShakingflag ensures only one shake happens at a time, preventing unintended intensity spikes.
How to Use It in Your Game
- Attach the script to a GameObject in your scene.
- Assign your Cinemachine Virtual Camera in the Inspector.
- Set an AnimationCurve for the shake effect (e.g., start strong and fade out).
- Trigger the shake using the command below. This will shake the camera for 0.5 seconds.
CinemachineShake.cinemachineShake.StartShakeCamera(0.5f);
Customizing the Shake Effect
You can tweak the shake to match your game's feel:
- Adjust
shakeIntensityfor a stronger or weaker shake. - Modify the
AnimationCurveto fine-tune how the shake fades in/out. - Experiment with
m_AmplitudeGainandm_FrequencyGainin Cinemachine for different effects.
Final Thoughts
Camera shake is a simple but powerful way to enhance feedback in your game. With this Cinemachine Shake system, you can easily create immersive effects for explosions, collisions, and more. Try it out, tweak the parameters, and let your game feel more alive than ever!
