Creating screen shakes in unity games.
Using Cinemachine
This post was written as a guide for anyone who wants to add screen shake functionality into their gaming experience, especially if it is during the polishing phase, leading to closed testing. I am writing this post under the assumption that you have a working game, created using the unity game engine and you are using cinemachine to control camera movement.
Below is a step by step guide I've used to create the shake effect in my game “maaze”.
Step #1
The first step is to find the virtual camera, used by Cinemachine to control player movements, if you don’t have a virtual camera, you can create one by following this guide.
Step #2
Locate the Noise component, as displayed in the screenshot above, change the noise signal from “none” to “Basic multi-channel Perlin”. Choose from any of the lists of noise profiles I recommend using “6D Shake’. To test how the shake functionality, enter play mode and change then “Amplitude Gain”, which will result in the camera shake effect. Now it’s time to create a script that will change “Amplitude Gain” to a predetermined value and then set it back after some time.
Step #3
Create a folder as shown in the screenshot to keep all scripts that Cinemachine modify scene machine, create a “CinemachineScreenShake” script and copy the snippet below into the script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// import cinemachine
using Cinemachine;public class CinemachineScreenShake : MonoBehaviour{
// create a static instance with public get method for calling the shake functionality.
public static CinemachineScreenShake Instance {get; private set;}private CinemachineVirtualCamera cinemachineVirtualCamera;
private float shakeTime;private void Awake() {
// assign class to the static instance
Instance = this;// get reference to the cinemachine virtual camera
cinemachineVirtualCamera = GetComponent<CinemachineVirtualCamera>();
}// screenshake functionality
public void ShakeCamera(float shakeIntensity, float time){
CinemachineBasicMultiChannelPerlin cinemachineBasicMultiChannelPerlin = cinemachineVirtualCamera.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
cinemachineBasicMultiChannelPerlin.m_AmplitudeGain = shakeIntensity;
shakeTime = time;
}// Update is called once per frame
void Update(){
if (shakeTime > 0){
shakeTime -= Time.deltaTime;
}if (shakeTime <= 0){
// Timer over!
CinemachineBasicMultiChannelPerlin cinemachineBasicMultiChannelPerlin = cinemachineVirtualCamera.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
cinemachineBasicMultiChannelPerlin.m_AmplitudeGain = 0.0f;
}}
}
The code below works by, creating a private “shakeCamera ”function, that shakes the player’s screen by setting the amplitude of “cinemachineBasicMultiChannelPerlin ”from zero to the value of “shakeIntensity ”passed by the calling function. The “shakeCamera ”function is exposed via a public static variable that prevents “shakeCamera” from being called by multiple instances.
Step #4
Attach the “CinemachineScreenShake” script, to the virtual camera.
Step #5
Find out the key places you want your shake function to be called from, and call the static instance of “CinemachineScreenShake” as shown below.
// I advice you experiment with these values to find what works for your game.
float shakeIntensity = 1.0f;
float shakeTime = 0.50f;
CinemachineScreenShake.Instance.ShakeCamera(1.0f, 0.50f);
Thanks for reading till the end! Hope it helps… 👩💻
Feel free to get in touch with me on Twitter for your queries or just to say Hi!