Last active
February 22, 2017 02:28
-
-
Save luciditee/6c8ff710479631b1bd880766e36a8026 to your computer and use it in GitHub Desktop.
A simple Unity script designed to shake the screen both via rotation and position.
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
/* | |
* Unity Screen Shake: A simple script designed to shake the | |
* attached transform using rotation and position; usually parented | |
* to a camera. | |
* | |
* Copyright 2016-2017 Will Preston & Die-Cast Magic Studios, LLC. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* | |
*/ | |
using UnityEngine; | |
public sealed class ScreenShake : MonoBehaviour { | |
// How rapidly the screenshake finds a new target. | |
[Range(10f, 100f)] | |
public float frequency = 10f; | |
// How large is the delta of each shake? | |
[Range(.1f, 1f)] | |
public float intensity = 1f; | |
// How much influence should we have on the position? | |
[Range(0.01f, 1f)] | |
public float positionMultiplier = .2f; | |
private bool doShake = false; // Internally, are we shaking? | |
private float timer = 0f; // Frequency timer. | |
private float opTimer = 0f; // Operation timer (for when we call Shake()) | |
private float maxOpTimer = 0f; // How long should a Shake() last? | |
private float opIntensity = 1f; // How intense should a Shake() be? | |
private float lerpIntensity = 0f; // Lerp from 0 to opIntensity and back. | |
private float propagationSpeed = 1f; // How quickly does the lerp kick in? | |
private bool sign = false; // Return to original position or new position? | |
private Quaternion targetRotation = Quaternion.identity; // Lerp target. | |
private Vector3 targetPosition = Vector3.zero; // Lerp target. | |
// Create a screenshake based on the intensity set and duration. | |
public void Shake(float intensity, float duration, float propagation = 3f) { | |
propagationSpeed = Mathf.Clamp(propagation, 1f, 10f); | |
opIntensity = intensity; | |
maxOpTimer = duration; | |
opTimer = 0f; | |
doShake = true; | |
} | |
// Once per frame, update. | |
void Update () { | |
if (doShake) { | |
// Add to the op timer. | |
opTimer += Time.deltaTime; | |
// We 'fake' the frequency by counting up to the reciprocal value of the Hz specified | |
// by the inspector (this converts from Hz to seconds). When this count-up succeeds, | |
// we reset the timer. | |
timer += Time.deltaTime; | |
if (timer >= (1f/frequency)) { | |
timer = 0f; | |
// The 'sign' merely predicts if we're on a tick or tock, i.e. if we are | |
// moving towards our base position/rotation or towards a randomized one. | |
if (sign) { | |
targetRotation = Quaternion.identity; | |
targetPosition = Vector3.zero; | |
} else { | |
float intensity = this.intensity * lerpIntensity; | |
targetRotation = Quaternion.Euler(Random.Range(-intensity, intensity), | |
Random.Range(-intensity, intensity), Random.Range(-intensity, intensity)); | |
targetPosition = (new Vector3(Random.Range(-intensity, intensity), Random.Range(-intensity, intensity), | |
Random.Range(-intensity, intensity)) * positionMultiplier); | |
} | |
// Flip the sign. | |
sign = !sign; | |
} | |
// Break out if we are done. | |
if (opTimer >= maxOpTimer) { | |
doShake = false; | |
opIntensity = 0f; | |
opTimer = 0f; | |
} | |
} else { | |
// If we are not shaking, force this to an identity transform. | |
targetRotation = Quaternion.identity; | |
targetPosition = Vector3.zero; | |
} | |
// Perform move. | |
transform.localPosition = Vector3.Lerp(transform.localPosition, targetPosition, Time.deltaTime*propagationSpeed); | |
transform.localRotation = Quaternion.Slerp(transform.localRotation, targetRotation, Time.deltaTime*propagationSpeed); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment