Camera Shake
Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 48 of 63.
A shake is a short run of random offsets: for a few tenths of a second the camera sits at a random spot near its rest position, a new one on every frame, and then it goes back. A coroutine fits, because it runs over several frames and ends by itself. This camera shakes when a boulder lands (another script calls BoulderLanded(); the file starts with using System.Collections; for IEnumerator):
public float strength = 0.2f;
public float duration = 0.4f;
Vector3 rest;
void Start()
{
rest = transform.localPosition;
}
public void BoulderLanded()
{
StartCoroutine(Shake());
}
IEnumerator Shake()
{
float elapsed = 0f;
while (elapsed < duration)
{
transform.localPosition = rest + Random.insideUnitSphere * strength;
elapsed += Time.deltaTime;
yield return null;
}
transform.localPosition = rest;
}Random.insideUnitSphere * strength is a random offset up to strength long in any direction, and yield return null picks a new one on the next frame. Adding Time.deltaTime each pass counts real seconds, so the shake lasts duration at any frame rate. The last line puts the camera back; without it, the camera stays wherever the last offset left it.
On each frame Unity runs every Update(), then the coroutines waiting on yield return null, then every LateUpdate(). So a follow camera that sets its position in LateUpdate() overwrites whatever the shake did. Shaking localPosition avoids that when the camera is the child of an empty object that does the following: the parent moves, and the camera shakes around its spot under it.
Challenge
MediumThis camera follows the player (the arrows move it): in LateUpdate() it sits at the player's position plus offset, and it is not the child of anything. Give it a shake that works while it follows:
- Space shakes it for
duration(0.4) seconds. On every frame of the shake the camera is at a new random spot up tostrength(0.3) from its follow position, while it keeps following the player. - When the shake ends, it is back exactly on its follow position.
Space already starts the Shake() coroutine. Press Play, run and press Space, then Check.
Try it yourself
using System.Collections;
using UnityEngine;
public class ShakeFollow : MonoBehaviour
{
public Transform player;
public Vector3 offset = new Vector3(0, 4, -8);
public float strength = 0.3f;
public float duration = 0.4f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(Shake());
}
}
void LateUpdate()
{
transform.position = player.position + offset;
}
IEnumerator Shake()
{
// Shake the camera for duration seconds, up to strength from its follow position.
yield return null;
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Physics and Gameplay
1Rigidbody
Gravity and MassPush with AddForceJump with an ImpulseFixedUpdate for PhysicsVelocityKinematic BodiesRecap: Launch Pad2Collisions
OnCollisionEnterWhat Did I Hit?Break on ImpactStanding on the GroundBounce and FrictionCollider ShapesRecap: Breakable Wall