245 lines
9.1 KiB
C#
245 lines
9.1 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
|
|
namespace MirzaBeig
|
|
{
|
|
|
|
namespace ParticleSystems
|
|
{
|
|
|
|
namespace Demos
|
|
{
|
|
|
|
public enum CameraShakeTarget
|
|
{
|
|
Position,
|
|
Rotation
|
|
}
|
|
public enum CameraShakeAmplitudeCurve
|
|
{
|
|
Constant,
|
|
|
|
// Fade in fully at 25%, 50%, and 75% of lifetime.
|
|
|
|
FadeInOut25,
|
|
FadeInOut50,
|
|
FadeInOut75,
|
|
}
|
|
public enum CameraShakeAmplitudeOverDistanceCurve
|
|
{
|
|
Constant,
|
|
|
|
LinearFadeIn,
|
|
LinearFadeOut
|
|
}
|
|
|
|
public class CameraShake : MonoBehaviour
|
|
{
|
|
[System.Serializable]
|
|
public class Shake
|
|
{
|
|
public float amplitude = 1.0f;
|
|
public float frequency = 1.0f;
|
|
|
|
public float duration;
|
|
|
|
[HideInInspector]
|
|
public CameraShakeTarget target;
|
|
|
|
float timeRemaining;
|
|
|
|
Vector2 perlinNoiseX;
|
|
Vector2 perlinNoiseY;
|
|
Vector2 perlinNoiseZ;
|
|
|
|
[HideInInspector]
|
|
public Vector3 noise;
|
|
|
|
public AnimationCurve amplitudeOverLifetimeCurve = new AnimationCurve(new Keyframe(0.0f, 1.0f), new Keyframe(1.0f, 0.0f));
|
|
|
|
public void Init()
|
|
{
|
|
timeRemaining = duration;
|
|
ApplyRandomSeed();
|
|
}
|
|
void Init(float amplitude, float frequency, float duration, CameraShakeTarget target)
|
|
{
|
|
this.amplitude = amplitude;
|
|
this.frequency = frequency;
|
|
|
|
this.duration = duration;
|
|
timeRemaining = duration;
|
|
|
|
this.target = target;
|
|
|
|
ApplyRandomSeed();
|
|
}
|
|
|
|
public void ApplyRandomSeed()
|
|
{
|
|
float randomRange = 32.0f;
|
|
|
|
perlinNoiseX.x = Random.Range(-randomRange, randomRange);
|
|
perlinNoiseX.y = Random.Range(-randomRange, randomRange);
|
|
|
|
perlinNoiseY.x = Random.Range(-randomRange, randomRange);
|
|
perlinNoiseY.y = Random.Range(-randomRange, randomRange);
|
|
|
|
perlinNoiseZ.x = Random.Range(-randomRange, randomRange);
|
|
perlinNoiseZ.y = Random.Range(-randomRange, randomRange);
|
|
}
|
|
|
|
public Shake(float amplitude, float frequency, float duration, CameraShakeTarget target, AnimationCurve amplitudeOverLifetimeCurve)
|
|
{
|
|
Init(amplitude, frequency, duration, target);
|
|
this.amplitudeOverLifetimeCurve = amplitudeOverLifetimeCurve;
|
|
}
|
|
|
|
public Shake(float amplitude, float frequency, float duration, CameraShakeTarget target, CameraShakeAmplitudeCurve amplitudeOverLifetimeCurve)
|
|
{
|
|
Init(amplitude, frequency, duration, target);
|
|
|
|
switch (amplitudeOverLifetimeCurve)
|
|
{
|
|
case CameraShakeAmplitudeCurve.Constant:
|
|
{
|
|
this.amplitudeOverLifetimeCurve = AnimationCurve.Linear(0.0f, 1.0f, 1.0f, 1.0f);
|
|
break;
|
|
}
|
|
case CameraShakeAmplitudeCurve.FadeInOut25:
|
|
{
|
|
this.amplitudeOverLifetimeCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f), new Keyframe(0.25f, 1.0f), new Keyframe(1.0f, 0.0f));
|
|
break;
|
|
}
|
|
case CameraShakeAmplitudeCurve.FadeInOut50:
|
|
{
|
|
this.amplitudeOverLifetimeCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f), new Keyframe(0.50f, 1.0f), new Keyframe(1.0f, 0.0f));
|
|
break;
|
|
}
|
|
case CameraShakeAmplitudeCurve.FadeInOut75:
|
|
{
|
|
this.amplitudeOverLifetimeCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f), new Keyframe(0.75f, 1.0f), new Keyframe(1.0f, 0.0f));
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
throw new System.Exception("Unknown enum.");
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsAlive()
|
|
{
|
|
return timeRemaining > 0.0f;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (timeRemaining < 0.0f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector2 frequencyVector = Time.deltaTime * new Vector2(frequency, frequency);
|
|
|
|
perlinNoiseX += frequencyVector;
|
|
perlinNoiseY += frequencyVector;
|
|
perlinNoiseZ += frequencyVector;
|
|
|
|
noise.x = Mathf.PerlinNoise(perlinNoiseX.x, perlinNoiseX.y) - 0.5f;
|
|
noise.y = Mathf.PerlinNoise(perlinNoiseY.x, perlinNoiseY.y) - 0.5f;
|
|
noise.z = Mathf.PerlinNoise(perlinNoiseZ.x, perlinNoiseZ.y) - 0.5f;
|
|
|
|
float amplitudeOverLifetime = amplitudeOverLifetimeCurve.Evaluate(1.0f - (timeRemaining / duration));
|
|
|
|
noise *= amplitude * amplitudeOverLifetime;
|
|
|
|
timeRemaining -= Time.deltaTime;
|
|
}
|
|
}
|
|
|
|
// ...
|
|
|
|
public float smoothDampTime = 0.025f;
|
|
|
|
Vector3 smoothDampPositionVelocity;
|
|
|
|
float smoothDampRotationVelocityX;
|
|
float smoothDampRotationVelocityY;
|
|
float smoothDampRotationVelocityZ;
|
|
|
|
List<Shake> shakes = new List<Shake>();
|
|
|
|
// ...
|
|
|
|
void Start()
|
|
{
|
|
|
|
}
|
|
|
|
// ...
|
|
|
|
public void Add(float amplitude, float frequency, float duration, CameraShakeTarget target, AnimationCurve amplitudeOverLifetimeCurve)
|
|
{
|
|
shakes.Add(new Shake(amplitude, frequency, duration, target, amplitudeOverLifetimeCurve));
|
|
}
|
|
public void Add(float amplitude, float frequency, float duration, CameraShakeTarget target, CameraShakeAmplitudeCurve amplitudeOverLifetimeCurve)
|
|
{
|
|
shakes.Add(new Shake(amplitude, frequency, duration, target, amplitudeOverLifetimeCurve));
|
|
}
|
|
|
|
// ...
|
|
|
|
void Update()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.F))
|
|
{
|
|
Add(0.25f, 1.0f, 2.0f, CameraShakeTarget.Position, CameraShakeAmplitudeCurve.FadeInOut25);
|
|
}
|
|
if (Input.GetKeyDown(KeyCode.G))
|
|
{
|
|
Add(15.0f, 1.0f, 2.0f, CameraShakeTarget.Rotation, CameraShakeAmplitudeCurve.FadeInOut25);
|
|
}
|
|
|
|
if (Input.GetKey(KeyCode.H))
|
|
{
|
|
|
|
}
|
|
|
|
Vector3 positionOffset = Vector3.zero;
|
|
Vector3 rotationOffset = Vector3.zero;
|
|
|
|
for (int i = 0; i < shakes.Count; i++)
|
|
{
|
|
shakes[i].Update();
|
|
|
|
if (shakes[i].target == CameraShakeTarget.Position)
|
|
{
|
|
positionOffset += shakes[i].noise;
|
|
}
|
|
else
|
|
{
|
|
rotationOffset += shakes[i].noise;
|
|
}
|
|
}
|
|
|
|
shakes.RemoveAll(x => !x.IsAlive());
|
|
|
|
transform.localPosition = Vector3.SmoothDamp(transform.localPosition, positionOffset, ref smoothDampPositionVelocity, smoothDampTime);
|
|
|
|
Vector3 eulerAngles = transform.localEulerAngles;
|
|
|
|
eulerAngles.x = Mathf.SmoothDampAngle(eulerAngles.x, rotationOffset.x, ref smoothDampRotationVelocityX, smoothDampTime);
|
|
eulerAngles.y = Mathf.SmoothDampAngle(eulerAngles.y, rotationOffset.y, ref smoothDampRotationVelocityY, smoothDampTime);
|
|
eulerAngles.z = Mathf.SmoothDampAngle(eulerAngles.z, rotationOffset.z, ref smoothDampRotationVelocityZ, smoothDampTime);
|
|
|
|
transform.localEulerAngles = eulerAngles;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|