Skip to content

Rewrite of cameraShake #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 43 additions & 35 deletions Assets/Scripts/Camera/CameraShake.cs
Original file line number Diff line number Diff line change
@@ -1,58 +1,66 @@
using UnityEngine;
using System.Collections;

// usage: attach this script into camera, call Shake() method to start
// source: http://answers.unity3d.com/answers/992509/view.html
/*
* Usage: attach this script to a camera or any other object, call Shake() method to start shaking it
* To turn off, change influence to zero
* Attach the camera to an empty game object to keep its local position and rotation
*/
namespace UnityLibrary
{
public class CameraShake : MonoBehaviour
{
public bool shakePosition;
public bool shakeRotation;

public float shakeIntensityMin = 0.1f;
public float shakeIntensityMax = 0.5f;
public float shakeDecay = 0.02f;
[Range(0f, 1f)]
public float shakeInfluence = 0.5f;
[Range(0f, 10f)]
public float rotationInfluence = 0f;

private Vector3 OriginalPos;
private Quaternion OriginalRot;

private bool isShakeRunning = false;

// call this function to start shaking
public void Shake()
/// <summary>
/// Will shake the camera with a random value between minIntensity and maxIntensity for duration
/// </summary>
/// <param name="minIntensity"></param>
/// <param name="maxIntensity"></param>
/// <param name="duration"></param>
public void Shake(float minIntensity, float maxIntensity, float duration)
{
if (isShakeRunning)
return;

OriginalPos = transform.position;
OriginalRot = transform.rotation;
StartCoroutine("ProcessShake");

float shake = Random.Range(minIntensity, maxIntensity) * shakeInfluence;
duration *= shakeInfluence;

StartCoroutine(ProcessShake(shake, duration));
}

IEnumerator ProcessShake()
IEnumerator ProcessShake(float shake, float duration)
{
if (!isShakeRunning)
isShakeRunning = true;
float countdown = duration;
float initialShake = shake;

while (countdown > 0)
{
isShakeRunning = true;
float currentShakeIntensity = Random.Range(shakeIntensityMin, shakeIntensityMax);

while (currentShakeIntensity > 0)
{
if (shakePosition)
{
transform.position = OriginalPos + Random.insideUnitSphere * currentShakeIntensity;
}
if (shakeRotation)
{
transform.rotation = new Quaternion(OriginalRot.x + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f,
OriginalRot.y + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f,
OriginalRot.z + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f,
OriginalRot.w + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f);
}
currentShakeIntensity -= shakeDecay;
yield return null;
}

isShakeRunning = false;
countdown -= Time.deltaTime;

float lerpIntensity = countdown / duration;
shake = Mathf.Lerp(0f, initialShake, lerpIntensity);

transform.position = OriginalPos + Random.insideUnitSphere * shake;
transform.rotation = Quaternion.Euler(OriginalRot.eulerAngles + Random.insideUnitSphere * shake * rotationInfluence);

yield return null;
}

transform.position = OriginalPos;
transform.rotation = OriginalRot;
isShakeRunning = false;
}
}
}