Camera Shake in Unity
I assumed this was going to be an easy feature to add to my game, but nothing in programming is, especially a beginning GameDev. After some research on how to create the camera shake effect, there was many different ways to accomplish it. There as a method using Animations, Cinemachine or using Script. This is article will cover how to create a script to create the Camera Shake effect. Now, this script was taken from Brackeys and you can check out the video by clicking on the link below.
We are going to create and attach a script to the Main Camera in the scene. This Camera Shake Effect is going to be created in a Coroutine. A Coroutine allows for the use in of a wait time or pause, which will be important.
To create a Coroutine, we use an IEnumerator and name it (“Shake”) and add a few parameters. The parameters are going to both be floats with one going to be the “duration” of the shake and the other will be the “magnitude” (strength) of the shake. This coroutine needs to be public so we can access it from another script.
The first thing in the coroutine is to create a Vector3 variable that will hold the camera’s original position before it shakes. Now, it is the usual transform.position but will be transform.localPosition which will get the position of the GameObject(camera) relative to the Parent object. This will come into play later.
Next, we will need to keep track of how long the camera is shaking, so this will be stored into a float variable and set to 0.
Getting into the meat of the code, we are going to use a While loop and the loop will run while the elapsed time is less than the duration of the shake that is determined using the parameter.
To actually move the camera we need to manipulate the X and Y of the camera and move it randomly to get the shake. We will create float variables for the x and y and make it a random number between -1 and 1. These will be multiple the magnitude(strength of the shake) parameter. Once we have these random x, y variables we can apply it to reposition the camera using a new Vector3.
The next step is adding to the elapsed time, so we can eventually get out of the While loop when this elasped time is greater than the duration parameter. We add to elasped time be adding Time.deltaTime, which is the amount of time that passed from the last frame drawn to the current frame.
Lastly, we need to yield return null (in while loops you always need yield a wait time to give your program to breather between each pass during the While loop). Yield return null will wait until the next frame is drawn before moving onto the next step (breathe!).
Once the While Loop is done, we need to set the camera back to its original position. Now we are done with the Camera Shake script.
Now we can apply this camera script to whenever we want it to occur and I will be applying when the Player takes damage. On the player script we need to get a handle on the CameraShake, so we will create a variable.
Lets add the Camera to the Player in the Inspector.
We have Camera Shake! But, it is snapping and a bit jarring. The cause could be the camera already has a position in the scene and the shaking is messing with it.
In fixing this, we need to constrain the camera by creating an empty GameObject as its holder. We first want to make sure the Camera Holder has the same position as the Camera, so we make it a child of the Camera and reset the Transform. Now, we unchild the Camera Holder and make the Camera a child of the Camera Holder. The Camera Holder will maintain the Cameras original position and the Camera will shake in the context of the Holder position. Remember the transform.localPosition. This keeps it positions it relative to the Camera Holder, which isn’t moving so we don’t get that snapping we did before when it was just the Camera.
That is it! Now, we have script we call on other GameObjects when we want the Shake Camera effect.