Created
March 5, 2018 23:44
-
-
Save slonermike/40cb25549b4428ec9221c00b0b73e570 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
// TODO: Is there really anything about this that makes it | |
// specific to cameras? This logic could be used to shake | |
// anything. Only thing tying it to that is the ShakeAllCameras | |
// functionality but we could work that out by tagging things by | |
// generic categories, and shaking all objects in a category. | |
// | |
public class CameraShaker : MonoBehaviour { | |
private static List<CameraShaker> shakers = new List<CameraShaker>(); | |
public float rotationFactor = 1f; | |
float maxMagnitude = 0.0f; | |
float timeLeft_s = 0.0f; | |
float timeTotal_s = 0.0f; | |
// Activate every CameraShaker in the scene. | |
// | |
// time_s: Time (in seconds) for the shake to take. | |
// magnitude: distance (in game units) for the shake to move the camera at its most extreme. | |
// | |
public static void ShakeAllCameras(float time_s, float magnitude) | |
{ | |
foreach (CameraShaker s in shakers) { | |
s.Shake (time_s, magnitude); | |
} | |
} | |
void Start () { | |
// Add it to the global list of camera shakers. | |
shakers.Add (this); | |
} | |
void OnDestroy() { | |
shakers.Remove (this); | |
} | |
void Update () { | |
// Subtract time until it reaches zero, then the shake is done. Reset the system. | |
timeLeft_s -= Time.deltaTime; | |
if (timeLeft_s <= 0.0f) { | |
timeLeft_s = 0.0f; | |
timeTotal_s = 0.0f; | |
maxMagnitude = 0.0f; | |
} | |
// Set the local position to the shaken offset. | |
transform.localPosition = GetOffset (); | |
Vector3 rotation = GetRotation(transform.localPosition); | |
transform.localRotation = Quaternion.Euler (rotation); | |
} | |
// Generates a random camera offset based on the current state of the shake. | |
// | |
Vector2 GetOffset() | |
{ | |
// Default offset is zero -- no shake. | |
Vector2 offset = Vector2.zero; | |
// If there is a current shake in play. | |
if (timeLeft_s > 0f && timeTotal_s > 0f) { | |
// Choose a random direction. | |
float direction = Random.Range (0.0f, 360.0f); | |
// Create a vector (relative to camera orientation) with a random direction rotated around the forward axis. | |
offset = Quaternion.AngleAxis (direction, transform.forward) * transform.right; | |
// Determine the current effective spread (between 0 and maxSpread) and multiply the offset by that. | |
offset *= Mathf.Lerp (0.0f, maxMagnitude, timeLeft_s / timeTotal_s); | |
} | |
return offset; | |
} | |
Vector3 GetRotation(Vector2 offset) | |
{ | |
return new Vector3 (offset.y * rotationFactor, offset.x * rotationFactor, 0f); | |
} | |
// Begin a new shake. | |
// | |
// time_s: Time (in seconds) for the shake to take. | |
// magnitude: distance (in game units) for the shake to move the camera at its most extreme. | |
// | |
public void Shake(float time_s, float magnitude) | |
{ | |
if (magnitude >= maxMagnitude) { | |
maxMagnitude = magnitude; | |
timeLeft_s = Mathf.Max(time_s, timeLeft_s); | |
timeTotal_s = timeLeft_s; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment