Upload from upload_mods.ps1
This commit is contained in:
66
KFAttached/GG Camera Shake/Runtime/Attenuator.cs
Normal file
66
KFAttached/GG Camera Shake/Runtime/Attenuator.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains methods for changing strength and direction of shakes depending on their position.
|
||||
/// </summary>
|
||||
public static class Attenuator
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns multiplier for the strength of a shake, based on source and camera positions.
|
||||
/// </summary>
|
||||
public static float Strength(StrengthAttenuationParams pars, Vector3 sourcePosition, Vector3 cameraPosition)
|
||||
{
|
||||
Vector3 vec = cameraPosition - sourcePosition;
|
||||
float distance = Vector3.Scale(pars.axesMultiplier, vec).magnitude;
|
||||
float strength = Mathf.Clamp01(1 - (distance - pars.clippingDistance) / pars.falloffScale);
|
||||
|
||||
return Power.Evaluate(strength, pars.falloffDegree);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns displacement, opposite to the direction to the source in camera's local space.
|
||||
/// </summary>
|
||||
public static Displacement Direction(Vector3 sourcePosition, Vector3 cameraPosition, Quaternion cameraRotation)
|
||||
{
|
||||
Displacement direction = Displacement.Zero;
|
||||
direction.position = (cameraPosition - sourcePosition).normalized;
|
||||
direction.position = Quaternion.Inverse(cameraRotation) * direction.position;
|
||||
|
||||
direction.eulerAngles.x = direction.position.z;
|
||||
direction.eulerAngles.y = direction.position.x;
|
||||
direction.eulerAngles.z = -direction.position.x;
|
||||
|
||||
return direction;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class StrengthAttenuationParams
|
||||
{
|
||||
/// <summary>
|
||||
/// Radius in which shake doesn't lose strength.
|
||||
/// </summary>
|
||||
[Tooltip("Radius in which shake doesn't lose strength.")]
|
||||
public float clippingDistance = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Defines how fast strength falls with distance.
|
||||
/// </summary>
|
||||
[Tooltip("How fast strength falls with distance.")]
|
||||
public float falloffScale = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Power of the falloff function.
|
||||
/// </summary>
|
||||
[Tooltip("Power of the falloff function.")]
|
||||
public Degree falloffDegree = Degree.Quadratic;
|
||||
|
||||
/// <summary>
|
||||
/// Contribution of each axis to distance. E. g. (1, 1, 0) for a 2D game in XY plane.
|
||||
/// </summary>
|
||||
[Tooltip("Contribution of each axis to distance. E. g. (1, 1, 0) for a 2D game in XY plane.")]
|
||||
public Vector3 axesMultiplier = Vector3.one;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/Attenuator.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/Attenuator.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07aa6a8400d46274f9cbc5f3714e6a9b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
133
KFAttached/GG Camera Shake/Runtime/BounceShake.cs
Normal file
133
KFAttached/GG Camera Shake/Runtime/BounceShake.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
public class BounceShake : ICameraShake
|
||||
{
|
||||
readonly Params pars;
|
||||
readonly AnimationCurve moveCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
|
||||
readonly Vector3? sourcePosition = null;
|
||||
|
||||
float attenuation = 1;
|
||||
Displacement direction;
|
||||
Displacement previousWaypoint;
|
||||
Displacement currentWaypoint;
|
||||
int bounceIndex;
|
||||
float t;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of BounceShake.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters of the shake.</param>
|
||||
/// <param name="sourcePosition">World position of the source of the shake.</param>
|
||||
public BounceShake(Params parameters, Vector3? sourcePosition = null)
|
||||
{
|
||||
this.sourcePosition = sourcePosition;
|
||||
pars = parameters;
|
||||
Displacement rnd = Displacement.InsideUnitSpheres();
|
||||
direction = Displacement.Scale(rnd, pars.axesMultiplier).Normalized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of BounceShake.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters of the shake.</param>
|
||||
/// <param name="initialDirection">Initial direction of the shake motion.</param>
|
||||
/// <param name="sourcePosition">World position of the source of the shake.</param>
|
||||
public BounceShake(Params parameters, Displacement initialDirection, Vector3? sourcePosition = null)
|
||||
{
|
||||
this.sourcePosition = sourcePosition;
|
||||
pars = parameters;
|
||||
direction = Displacement.Scale(initialDirection, pars.axesMultiplier).Normalized;
|
||||
}
|
||||
|
||||
public Displacement CurrentDisplacement { get; private set; }
|
||||
public bool IsFinished { get; private set; }
|
||||
public void Initialize(Vector3 cameraPosition, Quaternion cameraRotation)
|
||||
{
|
||||
attenuation = sourcePosition == null ?
|
||||
1 : Attenuator.Strength(pars.attenuation, sourcePosition.Value, cameraPosition);
|
||||
currentWaypoint = attenuation * direction.ScaledBy(pars.positionStrength, pars.rotationStrength);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime, Vector3 cameraPosition, Quaternion cameraRotation)
|
||||
{
|
||||
if (t < 1)
|
||||
{
|
||||
|
||||
t += deltaTime * pars.freq;
|
||||
if (pars.freq == 0) t = 1;
|
||||
|
||||
CurrentDisplacement = Displacement.Lerp(previousWaypoint, currentWaypoint,
|
||||
moveCurve.Evaluate(t));
|
||||
}
|
||||
else
|
||||
{
|
||||
t = 0;
|
||||
CurrentDisplacement = currentWaypoint;
|
||||
previousWaypoint = currentWaypoint;
|
||||
bounceIndex++;
|
||||
if (bounceIndex > pars.numBounces)
|
||||
{
|
||||
IsFinished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Displacement rnd = Displacement.InsideUnitSpheres();
|
||||
direction = -direction
|
||||
+ pars.randomness * Displacement.Scale(rnd, pars.axesMultiplier).Normalized;
|
||||
direction = direction.Normalized;
|
||||
float decayValue = 1 - (float)bounceIndex / pars.numBounces;
|
||||
currentWaypoint = decayValue * decayValue * attenuation
|
||||
* direction.ScaledBy(pars.positionStrength, pars.rotationStrength);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class Params
|
||||
{
|
||||
/// <summary>
|
||||
/// Strength of the shake for positional axes.
|
||||
/// </summary>
|
||||
[Tooltip("Strength of the shake for positional axes.")]
|
||||
public float positionStrength = 0.05f;
|
||||
|
||||
/// <summary>
|
||||
/// Strength of the shake for rotational axes.
|
||||
/// </summary>
|
||||
[Tooltip("Strength of the shake for rotational axes.")]
|
||||
public float rotationStrength = 0.1f;
|
||||
|
||||
/// <summary>
|
||||
/// Preferred direction of shaking.
|
||||
/// </summary>
|
||||
[Tooltip("Preferred direction of shaking.")]
|
||||
public Displacement axesMultiplier = new Displacement(Vector2.one, Vector3.forward);
|
||||
|
||||
/// <summary>
|
||||
/// Frequency of shaking.
|
||||
/// </summary>
|
||||
[Tooltip("Frequency of shaking.")]
|
||||
public float freq = 25;
|
||||
|
||||
/// <summary>
|
||||
/// Number of vibrations before stop.
|
||||
/// </summary>
|
||||
[Tooltip("Number of vibrations before stop.")]
|
||||
public int numBounces = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Randomness of motion.
|
||||
/// </summary>
|
||||
[Range(0, 1)]
|
||||
[Tooltip("Randomness of motion.")]
|
||||
public float randomness = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// How strength falls with distance from the shake source.
|
||||
/// </summary>
|
||||
[Tooltip("How strength falls with distance from the shake source.")]
|
||||
public Attenuator.StrengthAttenuationParams attenuation;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/BounceShake.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/BounceShake.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a8a4f5340889954aa6de7013b117066
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
113
KFAttached/GG Camera Shake/Runtime/CameraShakePresets.cs
Normal file
113
KFAttached/GG Camera Shake/Runtime/CameraShakePresets.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains shorthands for creating common shake types.
|
||||
/// </summary>
|
||||
public class CameraShakePresets
|
||||
{
|
||||
readonly CameraShaker shaker;
|
||||
|
||||
public CameraShakePresets(CameraShaker shaker)
|
||||
{
|
||||
this.shaker = shaker;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Suitable for short and snappy shakes in 2D. Moves camera in X and Y axes and rotates it in Z axis.
|
||||
/// </summary>
|
||||
/// <param name="positionStrength">Strength of motion in X and Y axes.</param>
|
||||
/// <param name="rotationStrength">Strength of rotation in Z axis.</param>
|
||||
/// <param name="freq">Frequency of shaking.</param>
|
||||
/// <param name="numBounces">Number of vibrations before stop.</param>
|
||||
public void ShortShake2D(
|
||||
float positionStrength = 0.08f,
|
||||
float rotationStrength = 0.1f,
|
||||
float freq = 25,
|
||||
int numBounces = 5)
|
||||
{
|
||||
BounceShake.Params pars = new BounceShake.Params
|
||||
{
|
||||
positionStrength = positionStrength,
|
||||
rotationStrength = rotationStrength,
|
||||
freq = freq,
|
||||
numBounces = numBounces
|
||||
};
|
||||
shaker.RegisterShake(new BounceShake(pars));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Suitable for longer and stronger shakes in 3D. Rotates camera in all three axes.
|
||||
/// </summary>
|
||||
/// <param name="strength">Strength of the shake.</param>
|
||||
/// <param name="freq">Frequency of shaking.</param>
|
||||
/// <param name="numBounces">Number of vibrations before stop.</param>
|
||||
public void ShortShake3D(
|
||||
float strength = 0.3f,
|
||||
float freq = 25,
|
||||
int numBounces = 5)
|
||||
{
|
||||
BounceShake.Params pars = new BounceShake.Params
|
||||
{
|
||||
axesMultiplier = new Displacement(Vector3.zero, new Vector3(1, 1, 0.4f)),
|
||||
rotationStrength = strength,
|
||||
freq = freq,
|
||||
numBounces = numBounces
|
||||
};
|
||||
shaker.RegisterShake(new BounceShake(pars));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Suitable for longer and stronger shakes in 2D. Moves camera in X and Y axes and rotates it in Z axis.
|
||||
/// </summary>
|
||||
/// <param name="positionStrength">Strength of motion in X and Y axes.</param>
|
||||
/// <param name="rotationStrength">Strength of rotation in Z axis.</param>
|
||||
/// <param name="duration">Duration of the shake.</param>
|
||||
public void Explosion2D(
|
||||
float positionStrength = 1f,
|
||||
float rotationStrength = 3,
|
||||
float duration = 0.5f)
|
||||
{
|
||||
PerlinShake.NoiseMode[] modes =
|
||||
{
|
||||
new PerlinShake.NoiseMode(8, 1),
|
||||
new PerlinShake.NoiseMode(20, 0.3f)
|
||||
};
|
||||
Envelope.EnvelopeParams envelopePars = new Envelope.EnvelopeParams();
|
||||
envelopePars.decay = duration <= 0 ? 1 : 1 / duration;
|
||||
PerlinShake.Params pars = new PerlinShake.Params
|
||||
{
|
||||
strength = new Displacement(new Vector3(1, 1) * positionStrength, Vector3.forward * rotationStrength),
|
||||
noiseModes = modes,
|
||||
envelope = envelopePars,
|
||||
};
|
||||
shaker.RegisterShake(new PerlinShake(pars));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Suitable for longer and stronger shakes in 3D. Rotates camera in all three axes.
|
||||
/// </summary>
|
||||
/// <param name="strength">Strength of the shake.</param>
|
||||
/// <param name="duration">Duration of the shake.</param>
|
||||
public void Explosion3D(
|
||||
float strength = 8f,
|
||||
float duration = 0.7f)
|
||||
{
|
||||
PerlinShake.NoiseMode[] modes =
|
||||
{
|
||||
new PerlinShake.NoiseMode(6, 1),
|
||||
new PerlinShake.NoiseMode(20, 0.2f)
|
||||
};
|
||||
Envelope.EnvelopeParams envelopePars = new Envelope.EnvelopeParams();
|
||||
envelopePars.decay = duration <= 0 ? 1 : 1 / duration;
|
||||
PerlinShake.Params pars = new PerlinShake.Params
|
||||
{
|
||||
strength = new Displacement(Vector3.zero, new Vector3(1, 1, 0.5f) * strength),
|
||||
noiseModes = modes,
|
||||
envelope = envelopePars,
|
||||
};
|
||||
shaker.RegisterShake(new PerlinShake(pars));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27cd455dd46fc6a47b7cc4f29f710304
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
98
KFAttached/GG Camera Shake/Runtime/CameraShaker.cs
Normal file
98
KFAttached/GG Camera Shake/Runtime/CameraShaker.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
/// <summary>
|
||||
/// Camera shaker component registeres new shakes, holds a list of active shakes, and applies them to the camera additively.
|
||||
/// </summary>
|
||||
public class CameraShaker : MonoBehaviour
|
||||
{
|
||||
public static CameraShaker Instance;
|
||||
public static CameraShakePresets Presets;
|
||||
|
||||
readonly List<ICameraShake> activeShakes = new List<ICameraShake>();
|
||||
|
||||
[Tooltip("Transform which will be affected by the shakes.\n\nCameraShaker will set this transform's local position and rotation.")]
|
||||
[SerializeField]
|
||||
Transform cameraTransform;
|
||||
|
||||
|
||||
[Tooltip("Scales the strength of all shakes.")]
|
||||
[Range(0, 1)]
|
||||
[SerializeField]
|
||||
public float StrengthMultiplier = 1;
|
||||
|
||||
public CameraShakePresets ShakePresets;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a shake to the list of active shakes.
|
||||
/// </summary>
|
||||
public static void Shake(ICameraShake shake)
|
||||
{
|
||||
if (IsInstanceNull()) return;
|
||||
Instance.RegisterShake(shake);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a shake to the list of active shakes.
|
||||
/// </summary>
|
||||
public void RegisterShake(ICameraShake shake)
|
||||
{
|
||||
shake.Initialize(cameraTransform.position,
|
||||
cameraTransform.rotation);
|
||||
activeShakes.Add(shake);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the transform which will be affected by the shakes.
|
||||
/// </summary>
|
||||
public void SetCameraTransform(Transform cameraTransform)
|
||||
{
|
||||
cameraTransform.localPosition = Vector3.zero;
|
||||
cameraTransform.localEulerAngles = Vector3.zero;
|
||||
this.cameraTransform = cameraTransform;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
ShakePresets = new CameraShakePresets(this);
|
||||
Presets = ShakePresets;
|
||||
if (cameraTransform == null)
|
||||
cameraTransform = transform;
|
||||
}
|
||||
|
||||
public void UpdateShake()
|
||||
{
|
||||
if (cameraTransform == null) return;
|
||||
|
||||
Displacement cameraDisplacement = Displacement.Zero;
|
||||
for (int i = activeShakes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (activeShakes[i].IsFinished)
|
||||
{
|
||||
activeShakes.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
activeShakes[i].Update(Time.deltaTime, cameraTransform.position, cameraTransform.rotation);
|
||||
cameraDisplacement += activeShakes[i].CurrentDisplacement;
|
||||
}
|
||||
}
|
||||
cameraTransform.localPosition = transform.localPosition + StrengthMultiplier * cameraDisplacement.position;
|
||||
cameraTransform.localRotation *= Quaternion.Euler(StrengthMultiplier * cameraDisplacement.eulerAngles);
|
||||
}
|
||||
|
||||
private static bool IsInstanceNull()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Debug.LogError("CameraShaker Instance is missing!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/CameraShaker.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/CameraShaker.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a257897ce04dc64eb5ae266c62846be
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
98
KFAttached/GG Camera Shake/Runtime/Displacement.cs
Normal file
98
KFAttached/GG Camera Shake/Runtime/Displacement.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
/// <summary>
|
||||
/// Representation of translation and rotation.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public struct Displacement
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector3 eulerAngles;
|
||||
|
||||
public Displacement(Vector3 position, Vector3 eulerAngles)
|
||||
{
|
||||
this.position = position;
|
||||
this.eulerAngles = eulerAngles;
|
||||
}
|
||||
|
||||
public Displacement(Vector3 position)
|
||||
{
|
||||
this.position = position;
|
||||
this.eulerAngles = Vector3.zero;
|
||||
}
|
||||
|
||||
public static Displacement Zero
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Displacement(Vector3.zero, Vector3.zero);
|
||||
}
|
||||
}
|
||||
|
||||
public static Displacement operator +(Displacement a, Displacement b)
|
||||
{
|
||||
return new Displacement(a.position + b.position,
|
||||
b.eulerAngles + a.eulerAngles);
|
||||
}
|
||||
|
||||
public static Displacement operator -(Displacement a, Displacement b)
|
||||
{
|
||||
return new Displacement(a.position - b.position,
|
||||
b.eulerAngles - a.eulerAngles);
|
||||
}
|
||||
|
||||
public static Displacement operator -(Displacement disp)
|
||||
{
|
||||
return new Displacement(-disp.position, -disp.eulerAngles);
|
||||
}
|
||||
|
||||
public static Displacement operator *(Displacement coords, float number)
|
||||
{
|
||||
return new Displacement(coords.position * number,
|
||||
coords.eulerAngles * number);
|
||||
}
|
||||
|
||||
public static Displacement operator *(float number, Displacement coords)
|
||||
{
|
||||
return coords * number;
|
||||
}
|
||||
|
||||
public static Displacement operator /(Displacement coords, float number)
|
||||
{
|
||||
return new Displacement(coords.position / number,
|
||||
coords.eulerAngles / number);
|
||||
}
|
||||
|
||||
public static Displacement Scale(Displacement a, Displacement b)
|
||||
{
|
||||
return new Displacement(Vector3.Scale(a.position, b.position),
|
||||
Vector3.Scale(b.eulerAngles, a.eulerAngles));
|
||||
}
|
||||
|
||||
public static Displacement Lerp(Displacement a, Displacement b, float t)
|
||||
{
|
||||
return new Displacement(Vector3.Lerp(a.position, b.position, t),
|
||||
Vector3.Lerp(a.eulerAngles, b.eulerAngles, t));
|
||||
}
|
||||
|
||||
public Displacement ScaledBy(float posScale, float rotScale)
|
||||
{
|
||||
return new Displacement(position * posScale, eulerAngles * rotScale);
|
||||
}
|
||||
|
||||
public Displacement Normalized
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Displacement(position.normalized, eulerAngles.normalized);
|
||||
}
|
||||
}
|
||||
|
||||
public static Displacement InsideUnitSpheres()
|
||||
{
|
||||
return new Displacement(Random.insideUnitSphere, Random.insideUnitSphere);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/Displacement.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/Displacement.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22dc566280f4a704d958e931abdb9fc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
168
KFAttached/GG Camera Shake/Runtime/Envelope.cs
Normal file
168
KFAttached/GG Camera Shake/Runtime/Envelope.cs
Normal file
@@ -0,0 +1,168 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls strength of the shake over time.
|
||||
/// </summary>
|
||||
public class Envelope : IAmplitudeController
|
||||
{
|
||||
readonly EnvelopeParams pars;
|
||||
readonly EnvelopeControlMode controlMode;
|
||||
|
||||
float amplitude;
|
||||
float targetAmplitude;
|
||||
float sustainEndTime;
|
||||
bool finishWhenAmplitudeZero;
|
||||
bool finishImmediately;
|
||||
EnvelopeState state;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an Envelope instance.
|
||||
/// </summary>
|
||||
/// <param name="pars">Envelope parameters.</param>
|
||||
/// <param name="controlMode">Pass Auto for a single shake, or Manual for controlling strength manually.</param>
|
||||
public Envelope(EnvelopeParams pars, float initialTargetAmplitude, EnvelopeControlMode controlMode)
|
||||
{
|
||||
this.pars = pars;
|
||||
this.controlMode = controlMode;
|
||||
SetTarget(initialTargetAmplitude);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value by which you want to multiply shake displacement.
|
||||
/// </summary>
|
||||
public float Intensity { get; private set; }
|
||||
|
||||
public bool IsFinished
|
||||
{
|
||||
get
|
||||
{
|
||||
if (finishImmediately) return true;
|
||||
return (finishWhenAmplitudeZero || controlMode == EnvelopeControlMode.Auto)
|
||||
&& amplitude <= 0 && targetAmplitude <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Finish()
|
||||
{
|
||||
finishWhenAmplitudeZero = true;
|
||||
SetTarget(0);
|
||||
}
|
||||
|
||||
public void FinishImmediately()
|
||||
{
|
||||
finishImmediately = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update is called every frame by the shake.
|
||||
/// </summary>
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (IsFinished) return;
|
||||
|
||||
if (state == EnvelopeState.Increase)
|
||||
{
|
||||
if (pars.attack > 0)
|
||||
amplitude += deltaTime * pars.attack;
|
||||
if (amplitude > targetAmplitude || pars.attack <= 0)
|
||||
{
|
||||
amplitude = targetAmplitude;
|
||||
state = EnvelopeState.Sustain;
|
||||
if (controlMode == EnvelopeControlMode.Auto)
|
||||
sustainEndTime = Time.time + pars.sustain;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state == EnvelopeState.Decrease)
|
||||
{
|
||||
|
||||
if (pars.decay > 0)
|
||||
amplitude -= deltaTime * pars.decay;
|
||||
if (amplitude < targetAmplitude || pars.decay <= 0)
|
||||
{
|
||||
amplitude = targetAmplitude;
|
||||
state = EnvelopeState.Sustain;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (controlMode == EnvelopeControlMode.Auto && Time.time > sustainEndTime)
|
||||
{
|
||||
SetTarget(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amplitude = Mathf.Clamp01(amplitude);
|
||||
Intensity = Power.Evaluate(amplitude, pars.degree);
|
||||
}
|
||||
|
||||
public void SetTargetAmplitude(float value)
|
||||
{
|
||||
if (controlMode == EnvelopeControlMode.Manual && !finishWhenAmplitudeZero)
|
||||
{
|
||||
SetTarget(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetTarget(float value)
|
||||
{
|
||||
targetAmplitude = Mathf.Clamp01(value);
|
||||
state = targetAmplitude > amplitude ? EnvelopeState.Increase : EnvelopeState.Decrease;
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class EnvelopeParams
|
||||
{
|
||||
/// <summary>
|
||||
/// How fast the amplitude rises.
|
||||
/// </summary>
|
||||
[Tooltip("How fast the amplitude increases.")]
|
||||
public float attack = 10;
|
||||
|
||||
/// <summary>
|
||||
/// How long in seconds the amplitude holds a maximum value.
|
||||
/// </summary>
|
||||
[Tooltip("How long in seconds the amplitude holds maximum value.")]
|
||||
public float sustain = 0;
|
||||
|
||||
/// <summary>
|
||||
/// How fast the amplitude falls.
|
||||
/// </summary>
|
||||
[Tooltip("How fast the amplitude decreases.")]
|
||||
public float decay = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Power in which the amplitude is raised to get intensity.
|
||||
/// </summary>
|
||||
[Tooltip("Power in which the amplitude is raised to get intensity.")]
|
||||
public Degree degree = Degree.Cubic;
|
||||
}
|
||||
|
||||
public enum EnvelopeControlMode { Auto, Manual }
|
||||
|
||||
public enum EnvelopeState { Sustain, Increase, Decrease }
|
||||
}
|
||||
|
||||
public interface IAmplitudeController
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets value to which amplitude will move over time.
|
||||
/// </summary>
|
||||
void SetTargetAmplitude(float value);
|
||||
|
||||
/// <summary>
|
||||
/// Sets amplitude to zero and finishes the shake when zero is reached.
|
||||
/// </summary>
|
||||
void Finish();
|
||||
|
||||
/// <summary>
|
||||
/// Immediately finishes the shake.
|
||||
/// </summary>
|
||||
void FinishImmediately();
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/Envelope.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/Envelope.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13084b7de651ead408d3f5ef8c6837b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
KFAttached/GG Camera Shake/Runtime/ICameraShake.cs
Normal file
27
KFAttached/GG Camera Shake/Runtime/ICameraShake.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
public interface ICameraShake
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents current position and rotation of the camera according to the shake.
|
||||
/// </summary>
|
||||
Displacement CurrentDisplacement { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Shake system will dispose the shake on the first frame when this is true.
|
||||
/// </summary>
|
||||
bool IsFinished { get; }
|
||||
|
||||
/// <summary>
|
||||
/// CameraShaker calls this when the shake is added to the list of active shakes.
|
||||
/// </summary>
|
||||
void Initialize(Vector3 cameraPosition, Quaternion cameraRotation);
|
||||
|
||||
/// <summary>
|
||||
/// CameraShaker calls this every frame on active shakes.
|
||||
/// </summary>
|
||||
void Update(float deltaTime, Vector3 cameraPosition, Quaternion cameraRotation);
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/ICameraShake.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/ICameraShake.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a062a4046bad80b469554a84b9b30cab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
121
KFAttached/GG Camera Shake/Runtime/KickShake.cs
Normal file
121
KFAttached/GG Camera Shake/Runtime/KickShake.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
public class KickShake : ICameraShake
|
||||
{
|
||||
readonly Params pars;
|
||||
readonly Vector3? sourcePosition;
|
||||
readonly bool attenuateStrength;
|
||||
|
||||
Displacement direction;
|
||||
Displacement prevWaypoint;
|
||||
Displacement currentWaypoint;
|
||||
bool release;
|
||||
float t;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of KickShake in the direction from the source to the camera.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters of the shake.</param>
|
||||
/// <param name="sourcePosition">World position of the source of the shake.</param>
|
||||
/// <param name="attenuateStrength">Change strength depending on distance from the camera?</param>
|
||||
public KickShake(Params parameters, Vector3 sourcePosition, bool attenuateStrength)
|
||||
{
|
||||
pars = parameters;
|
||||
this.sourcePosition = sourcePosition;
|
||||
this.attenuateStrength = attenuateStrength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of KickShake.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters of the shake.</param>
|
||||
/// <param name="direction">Direction of the kick.</param>
|
||||
public KickShake(Params parameters, Displacement direction)
|
||||
{
|
||||
pars = parameters;
|
||||
this.direction = direction.Normalized;
|
||||
}
|
||||
|
||||
public Displacement CurrentDisplacement { get; private set; }
|
||||
public bool IsFinished { get; private set; }
|
||||
|
||||
|
||||
public void Initialize(Vector3 cameraPosition, Quaternion cameraRotation)
|
||||
{
|
||||
if (sourcePosition != null)
|
||||
{
|
||||
direction = Attenuator.Direction(sourcePosition.Value, cameraPosition, cameraRotation);
|
||||
if (attenuateStrength)
|
||||
direction *= Attenuator.Strength(pars.attenuation, sourcePosition.Value, cameraPosition);
|
||||
}
|
||||
currentWaypoint = Displacement.Scale(direction, pars.strength);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime, Vector3 cameraPosition, Quaternion cameraRotation)
|
||||
{
|
||||
if (t < 1)
|
||||
{
|
||||
Move(deltaTime,
|
||||
release ? pars.releaseTime : pars.attackTime,
|
||||
release ? pars.releaseCurve : pars.attackCurve);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentDisplacement = currentWaypoint;
|
||||
prevWaypoint = currentWaypoint;
|
||||
if (release)
|
||||
{
|
||||
IsFinished = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
release = true;
|
||||
t = 0;
|
||||
currentWaypoint = Displacement.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Move(float deltaTime, float duration, AnimationCurve curve)
|
||||
{
|
||||
if (duration > 0)
|
||||
t += deltaTime / duration;
|
||||
else
|
||||
t = 1;
|
||||
CurrentDisplacement = Displacement.Lerp(prevWaypoint, currentWaypoint, curve.Evaluate(t));
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class Params
|
||||
{
|
||||
/// <summary>
|
||||
/// Strength of the shake for each axis.
|
||||
/// </summary>
|
||||
[Tooltip("Strength of the shake for each axis.")]
|
||||
public Displacement strength = new Displacement(Vector3.zero, Vector3.one);
|
||||
|
||||
/// <summary>
|
||||
/// How long it takes to move forward.
|
||||
/// </summary>
|
||||
[Tooltip("How long it takes to move forward.")]
|
||||
public float attackTime = 0.05f;
|
||||
public AnimationCurve attackCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// How long it takes to move back.
|
||||
/// </summary>
|
||||
[Tooltip("How long it takes to move back.")]
|
||||
public float releaseTime = 0.2f;
|
||||
public AnimationCurve releaseCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// How strength falls with distance from the shake source.
|
||||
/// </summary>
|
||||
[Tooltip("How strength falls with distance from the shake source.")]
|
||||
public Attenuator.StrengthAttenuationParams attenuation;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/KickShake.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/KickShake.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aacae9308ca14a04a8174bd35d85a1be
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
144
KFAttached/GG Camera Shake/Runtime/PerlinShake.cs
Normal file
144
KFAttached/GG Camera Shake/Runtime/PerlinShake.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace CameraShake
|
||||
{
|
||||
public class PerlinShake : ICameraShake
|
||||
{
|
||||
readonly Params pars;
|
||||
readonly Envelope envelope;
|
||||
|
||||
public IAmplitudeController AmplitudeController;
|
||||
|
||||
Vector2[] seeds;
|
||||
float time;
|
||||
Vector3? sourcePosition;
|
||||
float norm;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of PerlinShake.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters of the shake.</param>
|
||||
/// <param name="maxAmplitude">Maximum amplitude of the shake.</param>
|
||||
/// <param name="sourcePosition">World position of the source of the shake.</param>
|
||||
/// <param name="manualStrengthControl">Pass true if you want to control amplitude manually.</param>
|
||||
public PerlinShake(
|
||||
Params parameters,
|
||||
float maxAmplitude = 1,
|
||||
Vector3? sourcePosition = null,
|
||||
bool manualStrengthControl = false)
|
||||
{
|
||||
pars = parameters;
|
||||
envelope = new Envelope(pars.envelope, maxAmplitude,
|
||||
manualStrengthControl ?
|
||||
Envelope.EnvelopeControlMode.Manual : Envelope.EnvelopeControlMode.Auto);
|
||||
AmplitudeController = envelope;
|
||||
this.sourcePosition = sourcePosition;
|
||||
}
|
||||
|
||||
public Displacement CurrentDisplacement { get; private set; }
|
||||
public bool IsFinished { get; private set; }
|
||||
|
||||
public void Initialize(Vector3 cameraPosition, Quaternion cameraRotation)
|
||||
{
|
||||
seeds = new Vector2[pars.noiseModes.Length];
|
||||
norm = 0;
|
||||
for (int i = 0; i < seeds.Length; i++)
|
||||
{
|
||||
seeds[i] = Random.insideUnitCircle * 20;
|
||||
norm += pars.noiseModes[i].amplitude;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime, Vector3 cameraPosition, Quaternion cameraRotation)
|
||||
{
|
||||
if (envelope.IsFinished)
|
||||
{
|
||||
IsFinished = true;
|
||||
return;
|
||||
}
|
||||
time += deltaTime;
|
||||
envelope.Update(deltaTime);
|
||||
|
||||
Displacement disp = Displacement.Zero;
|
||||
for (int i = 0; i < pars.noiseModes.Length; i++)
|
||||
{
|
||||
disp += pars.noiseModes[i].amplitude / norm *
|
||||
SampleNoise(seeds[i], pars.noiseModes[i].freq);
|
||||
}
|
||||
|
||||
CurrentDisplacement = envelope.Intensity * Displacement.Scale(disp, pars.strength);
|
||||
if (sourcePosition != null)
|
||||
CurrentDisplacement *= Attenuator.Strength(pars.attenuation, sourcePosition.Value, cameraPosition);
|
||||
}
|
||||
|
||||
private Displacement SampleNoise(Vector2 seed, float freq)
|
||||
{
|
||||
Vector3 position = new Vector3(
|
||||
Mathf.PerlinNoise(seed.x + time * freq, seed.y),
|
||||
Mathf.PerlinNoise(seed.x, seed.y + time * freq),
|
||||
Mathf.PerlinNoise(seed.x + time * freq, seed.y + time * freq));
|
||||
position -= Vector3.one * 0.5f;
|
||||
|
||||
Vector3 rotation = new Vector3(
|
||||
Mathf.PerlinNoise(-seed.x - time * freq, -seed.y),
|
||||
Mathf.PerlinNoise(-seed.x, -seed.y - time * freq),
|
||||
Mathf.PerlinNoise(-seed.x - time * freq, -seed.y - time * freq));
|
||||
rotation -= Vector3.one * 0.5f;
|
||||
|
||||
return new Displacement(position, rotation);
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class Params
|
||||
{
|
||||
/// <summary>
|
||||
/// Strength of the shake for each axis.
|
||||
/// </summary>
|
||||
[Tooltip("Strength of the shake for each axis.")]
|
||||
public Displacement strength = new Displacement(Vector3.zero, new Vector3(2, 2, 0.8f));
|
||||
|
||||
/// <summary>
|
||||
/// Layers of perlin noise with different frequencies.
|
||||
/// </summary>
|
||||
[Tooltip("Layers of perlin noise with different frequencies.")]
|
||||
public NoiseMode[] noiseModes = { new NoiseMode(12, 1) };
|
||||
|
||||
/// <summary>
|
||||
/// Strength over time.
|
||||
/// </summary>
|
||||
[Tooltip("Strength of the shake over time.")]
|
||||
public Envelope.EnvelopeParams envelope;
|
||||
|
||||
/// <summary>
|
||||
/// How strength falls with distance from the shake source.
|
||||
/// </summary>
|
||||
[Tooltip("How strength falls with distance from the shake source.")]
|
||||
public Attenuator.StrengthAttenuationParams attenuation;
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public struct NoiseMode
|
||||
{
|
||||
public NoiseMode(float freq, float amplitude)
|
||||
{
|
||||
this.freq = freq;
|
||||
this.amplitude = amplitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frequency multiplier for the noise.
|
||||
/// </summary>
|
||||
[Tooltip("Frequency multiplier for the noise.")]
|
||||
public float freq;
|
||||
|
||||
/// <summary>
|
||||
/// Amplitude of the mode.
|
||||
/// </summary>
|
||||
[Tooltip("Amplitude of the mode.")]
|
||||
[Range(0, 1)]
|
||||
public float amplitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/PerlinShake.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/PerlinShake.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de97a9ba28783f34cae2c44c1d4446d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
KFAttached/GG Camera Shake/Runtime/Power.cs
Normal file
24
KFAttached/GG Camera Shake/Runtime/Power.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace CameraShake
|
||||
{
|
||||
public static class Power
|
||||
{
|
||||
public static float Evaluate(float value, Degree degree)
|
||||
{
|
||||
switch (degree)
|
||||
{
|
||||
case Degree.Linear:
|
||||
return value;
|
||||
case Degree.Quadratic:
|
||||
return value * value;
|
||||
case Degree.Cubic:
|
||||
return value * value * value;
|
||||
case Degree.Quadric:
|
||||
return value * value * value * value;
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Degree { Linear, Quadratic, Cubic, Quadric }
|
||||
}
|
||||
11
KFAttached/GG Camera Shake/Runtime/Power.cs.meta
Normal file
11
KFAttached/GG Camera Shake/Runtime/Power.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae1c138ac39e5704daa47650c0a286d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user