chunk 2: remaining non-audio non-NewImport assets
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace FirstGearGames.SmoothCameraShaker
|
||||
{
|
||||
|
||||
|
||||
|
||||
public class ShakableBase : MonoBehaviour
|
||||
{
|
||||
#region Types.
|
||||
public enum ShakerTypes
|
||||
{
|
||||
CameraShaker = 0,
|
||||
ObjectShaker = 1
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Tooltip("Shaker type to use. CameraShaker will subscribe to your current or otherwise configured CameraShaker. ObjectShaker will subscribe to the first ObjectShaker found on or in parented objects.")]
|
||||
[SerializeField]
|
||||
private ShakerTypes _shakerType = ShakerTypes.CameraShaker;
|
||||
/// <summary>
|
||||
/// Shaker type to use. CameraShaker will subscribe to your current or otherwise configured CameraShaker. ObjectShaker will subscribe to the first ObjectShaker found on or in parented objects.s
|
||||
/// </summary>
|
||||
public ShakerTypes ShakerType { get { return _shakerType; } }
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52ce313d243e43145988d09cfb991db6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 162991
|
||||
packageName: Smooth Camera Shaker
|
||||
packageVersion: 2.12
|
||||
assetPath: Assets/FirstGearGames/SmoothCameraShaker/Scripts/Shakables/ShakableBase.cs
|
||||
uploadId: 376379
|
||||
@@ -0,0 +1,558 @@
|
||||
using FirstGearGames.Utilities.Maths;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FirstGearGames.SmoothCameraShaker
|
||||
{
|
||||
|
||||
public class ShakableCanvas : ShakableBase
|
||||
{
|
||||
#region Types.
|
||||
private struct StartValues
|
||||
{
|
||||
public StartValues(Vector3 position, Vector3 rotation)
|
||||
{
|
||||
Position = position;
|
||||
Rotation = rotation;
|
||||
}
|
||||
/// <summary>
|
||||
/// Start position for an object.
|
||||
/// </summary>
|
||||
public readonly Vector3 Position;
|
||||
/// <summary>
|
||||
/// Start rotation for an object.
|
||||
/// </summary>
|
||||
public readonly Vector3 Rotation;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// True to shake when the default camera shaker does. False to specify a camera shaker to use.
|
||||
/// </summary>
|
||||
[Tooltip("True to shake when the default camera shaker does. False to specify a camera shaker to use.")]
|
||||
[SerializeField]
|
||||
private bool _useDefaultCameraShaker = true;
|
||||
/// <summary>
|
||||
/// Camera shaker to monitor.
|
||||
/// </summary>
|
||||
[Tooltip("Camera shaker to monitor.")]
|
||||
[SerializeField]
|
||||
private CameraShaker _cameraShaker = null;
|
||||
/// <summary>
|
||||
/// Sets a new CameraShaker to use. This method will do nothing if using ShakableObject as the ShakerType.
|
||||
/// </summary>
|
||||
/// <param name="shaker"></param>
|
||||
public void SetCameraShaker(CameraShaker shaker)
|
||||
{
|
||||
if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
return;
|
||||
|
||||
if (_useDefaultCameraShaker)
|
||||
{
|
||||
if (Debug.isDebugBuild) Debug.LogWarning("Cannot set CameraShaker with UseDefaultCameraShaker set. If you wish to change CameraShaker at run-time set UseDefaultCameraShaker to false before entering play.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeCameraShakers(_cameraShaker, shaker, true);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// True to create a parent object and attach children to it. The parent object will be shaken instead of each individual canvas child. If your direct children move at all this value must be true. Setting value as false may incur extra cost as well.
|
||||
/// </summary>
|
||||
[Tooltip("True to create a parent object and attach children to it. The parent object will be shaken instead of each individual canvas child. If your direct children move at all this value must be true. Setting value as false may incur extra cost as well.")]
|
||||
[Space(10)]
|
||||
[SerializeField]
|
||||
private bool _encapsulateChildren = true;
|
||||
/// <summary>
|
||||
/// True to watch for additional children to encapsulate. This may be false if you do not add direct children to this canvas at runtime.
|
||||
/// </summary>
|
||||
[Tooltip("True to watch for additional children to encapsulate. This may be false if you do not add direct children to this canvas at runtime.")]
|
||||
[SerializeField]
|
||||
private bool _monitorEncapsulation = false;
|
||||
/// <summary>
|
||||
/// Positional shakes are multiplied by this value. Lower values will result in a lower positional magnitude.
|
||||
/// </summary>
|
||||
[Tooltip("Positional shakes are multiplied by this value. Lower values will result in a lower positional magnitude.")]
|
||||
[SerializeField]
|
||||
private float _positionalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Rotational shakes are multiplied by this value. Lower values will result in lower ritational magnitude.
|
||||
/// </summary>
|
||||
[Tooltip("Rotational shakes are multiplied by this value. Lower values will result in lower rotational magnitude.")]
|
||||
[SerializeField]
|
||||
private float _rotationalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// True to randomly change influence direction when shaking starts.
|
||||
/// </summary>
|
||||
[Tooltip("True to randomly change influence direction when shaking starts.")]
|
||||
[Space(10)]
|
||||
[SerializeField]
|
||||
private bool _randomizeDirections = true;
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// Transform children are being attached to. This only exist if EncapsulateChildren is true.
|
||||
/// </summary>
|
||||
private RectTransform _parentRect;
|
||||
/// <summary>
|
||||
/// Start values for children of this transform.
|
||||
/// </summary>
|
||||
private Dictionary<Transform, StartValues> _childrenStartValues = new Dictionary<Transform, StartValues>();
|
||||
/// <summary>
|
||||
/// Next time to clean ChildrenStartValues.
|
||||
/// </summary>
|
||||
private float _nextCleanStartValuesTime;
|
||||
/// <summary>
|
||||
/// Current camera shaker this canvas is subscribed to.
|
||||
/// </summary>
|
||||
private CameraShaker _currentCameraShaker = null;
|
||||
/// <summary>
|
||||
/// ObjectShaker used for this object. May be null if not using ObjectShaker type.
|
||||
/// </summary>
|
||||
private ObjectShaker _objectShaker = null;
|
||||
/// <summary>
|
||||
/// Direction to multiply position by when shaking starts.
|
||||
/// </summary>
|
||||
private float _randomPositionMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Direction to multiply rotation by when shaking starts.
|
||||
/// </summary>
|
||||
private float _randomRotationMultiplier = 1f;
|
||||
#endregion
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
FirstInitialize();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
//Subscribe.
|
||||
ChangeSubscription(true);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
/* If fails to encapsulate new children then remove script.
|
||||
* Something unrecoverable went wrong. */
|
||||
if (_monitorEncapsulation && !EncapsulateChildren(false))
|
||||
{
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
CheckRemoveNullStartValues();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
//Unsubscribe.
|
||||
ChangeSubscription(false);
|
||||
|
||||
ResetOffsets();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use. Should only be cmpleted once.
|
||||
/// </summary>
|
||||
private void FirstInitialize()
|
||||
{
|
||||
//If using ObjectShaker type.
|
||||
if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
_objectShaker = GetComponentInParent<ObjectShaker>();
|
||||
if (_objectShaker == null)
|
||||
{
|
||||
Debug.LogError("ObjectShaker could not be found on or above object " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Canvas canvas = GetComponent<Canvas>();
|
||||
//Canvas null.
|
||||
if (canvas == null)
|
||||
{
|
||||
if (Debug.isDebugBuild) Debug.LogError("Canvas does not exist on this object, this script has been destroyed.");
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
//World space canvases already shake.
|
||||
if (canvas.renderMode == RenderMode.WorldSpace)
|
||||
{
|
||||
if (Debug.isDebugBuild) Debug.LogError("ShakeableCanvas is not needed for Canvas RenderMode.WorldSpace");
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
//Camera space canvases don't need this script when using matrix on the CameraShaker.
|
||||
if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
//Camera not set.
|
||||
if (canvas.worldCamera == null)
|
||||
{
|
||||
if (Debug.isDebugBuild) Debug.LogWarning("WorldCamera is not set for this canvas. Cannot determine if this script is needed. If the CameraShaker for your intended WorldCamera is Matrix this script is not needed.");
|
||||
}
|
||||
//Camera known.
|
||||
else
|
||||
{
|
||||
CameraShaker shaker = canvas.worldCamera.GetComponent<CameraShaker>();
|
||||
if (shaker == null)
|
||||
{
|
||||
if (Debug.isDebugBuild) Debug.LogWarning("CameraShaker not found on WorldCamera. If the CameraShaker for your intended WorldCamera will use Matrix this script is not needed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shaker.ShakeTechnique == CameraShaker.ShakeTechniques.Matrix)
|
||||
if (Debug.isDebugBuild) Debug.LogWarning("CameraShaker technique on WorldCamera is set to Matrix. This script is not needed for Matrix shake techniques. Ignore this message if you intend to change the ShakeTechnique.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Subscribe to the CameraShaker if not using default.
|
||||
if (!_useDefaultCameraShaker)
|
||||
ChangeCameraShakers(null, _cameraShaker, false);
|
||||
|
||||
//Encapsulation is enabled.
|
||||
if (_encapsulateChildren)
|
||||
{
|
||||
//Try to encapsulate children.
|
||||
if (!EncapsulateChildren(true))
|
||||
{
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//Encapsulation is disabled, be sure to disable monitor as well.
|
||||
else
|
||||
{
|
||||
_monitorEncapsulation = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes which CameraShaker to use when not using defualt CameraShaker.
|
||||
/// </summary>
|
||||
/// <param name="shaker"></param>
|
||||
/// <param name="subscribe"></param>
|
||||
private void ChangeCameraShakers(CameraShaker oldShaker, CameraShaker newShaker, bool resetOffsets = true)
|
||||
{
|
||||
//No change.
|
||||
if (oldShaker == newShaker)
|
||||
return;
|
||||
|
||||
_currentCameraShaker = newShaker;
|
||||
|
||||
//Since canvas subs and unsubs using OnEnable/Disable only change subscriptions if enabled.
|
||||
if (gameObject.activeInHierarchy)
|
||||
{
|
||||
//Offsets are automatically reset OnDisable, so only need to reset if active.
|
||||
if (resetOffsets)
|
||||
ResetOffsets();
|
||||
|
||||
ChangeCameraShakerSubscription(oldShaker, false);
|
||||
ChangeCameraShakerSubscription(newShaker, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulate children transforms into a newly created transform.
|
||||
/// </summary>
|
||||
private bool EncapsulateChildren(bool initialization)
|
||||
{
|
||||
if (!_encapsulateChildren)
|
||||
return true;
|
||||
|
||||
//If being run for the first time.
|
||||
if (initialization)
|
||||
{
|
||||
GameObject obj = new GameObject();
|
||||
//Shouldn't happen but just incase.
|
||||
if (obj == null)
|
||||
{
|
||||
if (Debug.isDebugBuild) Debug.LogError("Encapsulation failed because parent object could not be created.");
|
||||
return false;
|
||||
}
|
||||
//Add a rect since this is a UI object.
|
||||
_parentRect = obj.AddComponent<RectTransform>();
|
||||
//Shouldn't happen but just incase.
|
||||
if (_parentRect == null)
|
||||
{
|
||||
if (Debug.isDebugBuild) Debug.LogError("Encapsulation failed because parentRect could not be created.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Setup parent rect to be full screen/stretched.
|
||||
_parentRect.name = "ShakableParentRect";
|
||||
_parentRect.SetParent(transform);
|
||||
_parentRect.anchorMin = new Vector2(0f, 0f);
|
||||
_parentRect.anchorMax = new Vector2(1f, 1f);
|
||||
_parentRect.offsetMin = Vector2.zero;
|
||||
_parentRect.offsetMax = Vector2.zero;
|
||||
_parentRect.localScale = Vector3.one;
|
||||
_parentRect.localPosition = Vector3.zero;
|
||||
_parentRect.localEulerAngles = Vector3.zero;
|
||||
}
|
||||
|
||||
//If the parent rect somehow got destroyed, shouldn't be possible.
|
||||
if (_parentRect == null)
|
||||
return false;
|
||||
|
||||
int childCount = transform.childCount;
|
||||
|
||||
/* If parent rect is a child of this, and child count is 1 then no reason to go
|
||||
* further as there are no other children. This isn't considered a failure. */
|
||||
if (_parentRect.parent == transform && childCount == 1)
|
||||
return true;
|
||||
|
||||
/* Since the child collection of this transform will change
|
||||
* as children are re-ordered a local copy is set first
|
||||
* and navigated to ensure all children objects are set
|
||||
* properly. */
|
||||
|
||||
Transform[] children = new Transform[childCount];
|
||||
for (int i = 0; i < childCount; i++)
|
||||
children[i] = transform.GetChild(i);
|
||||
|
||||
//Child to rect parent if not rect parent.
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
if (children[i] != _parentRect.transform && children[i].gameObject.activeInHierarchy)
|
||||
children[i].SetParent(_parentRect, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region ShakeUpdates.
|
||||
/// <summary>
|
||||
/// Received when shaking starts when previously stopped on all Shakers.
|
||||
/// </summary>
|
||||
private void OnShakingStarted()
|
||||
{
|
||||
RandomizeDirections();
|
||||
}
|
||||
/// <summary>
|
||||
/// Received when shaking starts when previously stopped on all Shakers.
|
||||
/// </summary>
|
||||
private void CameraShaker_OnShakingStarted(CameraShaker obj)
|
||||
{
|
||||
OnShakingStarted();
|
||||
}
|
||||
/// <summary>
|
||||
/// Received when shaking starts when previously stopped on ObjectShaker.
|
||||
/// </summary>
|
||||
private void ObjectShaker_OnShakingStarted(ObjectShaker obj)
|
||||
{
|
||||
OnShakingStarted();
|
||||
}
|
||||
/// <summary>
|
||||
/// Received every update a shake occurs.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
private void CameraShaker_OnShakeUpdate(CameraShaker shaker, ShakeUpdate obj)
|
||||
{
|
||||
ShakeUpdateOccurred(obj);
|
||||
}
|
||||
/// <summary>
|
||||
/// Received every fixed update a shake occurs. Contains the shake values from last update.
|
||||
/// </summary>
|
||||
private void ObjectShaker_OnShakeUpdate(ObjectShaker arg1, ShakeUpdate arg2)
|
||||
{
|
||||
ShakeUpdateOccurred(arg2);
|
||||
}
|
||||
/// <summary>
|
||||
/// Called when a shake update occurs, wether it be from CameraShaker or ObjectShaker.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
private void ShakeUpdateOccurred(ShakeUpdate obj)
|
||||
{
|
||||
//No reason to shake if not active in scene.
|
||||
if (!gameObject.activeInHierarchy)
|
||||
return;
|
||||
|
||||
Vector3 positionalOffset = obj.Canvases.Position * _positionalMultiplier;
|
||||
Vector3 rotationalOffset = obj.Canvases.Rotation * _rotationalMultiplier;
|
||||
|
||||
//If using an encapsulation.
|
||||
if (_parentRect != null)
|
||||
{
|
||||
_parentRect.localPosition = positionalOffset;
|
||||
_parentRect.localEulerAngles = rotationalOffset;
|
||||
}
|
||||
//Not using encapsulation.
|
||||
else
|
||||
{
|
||||
foreach (Transform t in transform)
|
||||
{
|
||||
Vector3 pos;
|
||||
Vector3 rot;
|
||||
StartValues startValues;
|
||||
|
||||
//If already in dictionary.
|
||||
if (_childrenStartValues.TryGetValue(t, out startValues))
|
||||
{
|
||||
pos = startValues.Position + positionalOffset;
|
||||
rot = startValues.Rotation + rotationalOffset;
|
||||
}
|
||||
//Not yet in dictionary.
|
||||
else
|
||||
{
|
||||
_childrenStartValues.Add(t, new StartValues(t.localPosition, t.localEulerAngles));
|
||||
pos = t.localPosition + positionalOffset;
|
||||
rot = t.localEulerAngles + rotationalOffset;
|
||||
}
|
||||
|
||||
t.localPosition = pos;
|
||||
t.localEulerAngles = rot;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Updates random multipliers for shakable.
|
||||
/// </summary>
|
||||
private void RandomizeDirections()
|
||||
{
|
||||
if (!_randomizeDirections)
|
||||
return;
|
||||
|
||||
_randomPositionMultiplier = Floats.RandomlyFlip(_randomPositionMultiplier);
|
||||
_randomRotationMultiplier = Floats.RandomlyFlip(_randomRotationMultiplier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the offsets on children.
|
||||
/// </summary>
|
||||
private void ResetOffsets()
|
||||
{
|
||||
//If using an encapsulation.
|
||||
if (_parentRect != null)
|
||||
{
|
||||
_parentRect.localPosition = Vector3.zero;
|
||||
_parentRect.localEulerAngles = Vector3.zero;
|
||||
}
|
||||
//Not using encapsulation.
|
||||
else
|
||||
{
|
||||
foreach (KeyValuePair<Transform, StartValues> dict in _childrenStartValues)
|
||||
{
|
||||
if (dict.Key != null)
|
||||
{
|
||||
dict.Key.localPosition = dict.Value.Position;
|
||||
dict.Key.localEulerAngles = dict.Value.Rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Periodically removes null values from ChildrenStartValues. Should be called every frame.
|
||||
/// </summary>
|
||||
private void CheckRemoveNullStartValues()
|
||||
{
|
||||
//ParentRect is immune to this behaviour, not needed if using parent rect.
|
||||
if (_parentRect != null)
|
||||
return;
|
||||
|
||||
//Only clean every 30 seconds. More than enough to prevent a memory leak.
|
||||
if (Time.unscaledTime < _nextCleanStartValuesTime)
|
||||
return;
|
||||
_nextCleanStartValuesTime = Time.unscaledTime + 30f;
|
||||
|
||||
//Build a collection of null keys then remove them from the dictionary after.
|
||||
List<Transform> keysToRemove = new List<Transform>();
|
||||
foreach (KeyValuePair<Transform, StartValues> dict in _childrenStartValues)
|
||||
{
|
||||
if (dict.Key == null)
|
||||
keysToRemove.Add(dict.Key);
|
||||
}
|
||||
for (int i = 0; i < keysToRemove.Count; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
_childrenStartValues.Remove(keysToRemove[i]);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
#region Change subscriptions.
|
||||
/// <summary>
|
||||
/// Changes the subscription to a camera shaker.
|
||||
/// </summary>
|
||||
/// <param name="shaker"></param>
|
||||
/// <param name="subscribe"></param>
|
||||
private void ChangeCameraShakerSubscription(CameraShaker shaker, bool subscribe)
|
||||
{
|
||||
if (shaker == null)
|
||||
return;
|
||||
|
||||
if (subscribe)
|
||||
{
|
||||
shaker.OnShakeUpdate += CameraShaker_OnShakeUpdate;
|
||||
shaker.OnShakingStarted += CameraShaker_OnShakingStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
shaker.OnShakeUpdate -= CameraShaker_OnShakeUpdate;
|
||||
shaker.OnShakingStarted -= CameraShaker_OnShakingStarted;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes the subscription to the default camera shaker by using CameraShakerHandler.
|
||||
/// </summary>
|
||||
/// <param name="subscribe"></param>
|
||||
private void ChangeDefaultCameraShakerSubscription(bool subscribe)
|
||||
{
|
||||
if (subscribe)
|
||||
{
|
||||
CameraShakerHandler.OnShakeUpdate += CameraShaker_OnShakeUpdate;
|
||||
CameraShakerHandler.OnShakingStarted += CameraShaker_OnShakingStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
CameraShakerHandler.OnShakeUpdate -= CameraShaker_OnShakeUpdate;
|
||||
CameraShakerHandler.OnShakingStarted -= CameraShaker_OnShakingStarted;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes subscriptions based on current settings and shaker type.
|
||||
/// </summary>
|
||||
/// <param name="subscribe"></param>
|
||||
private void ChangeSubscription(bool subscribe)
|
||||
{
|
||||
//CameraShaker type.
|
||||
if (base.ShakerType == ShakerTypes.CameraShaker)
|
||||
{
|
||||
//If using default camera shaker then subscribe to default on enable.
|
||||
if (_useDefaultCameraShaker)
|
||||
ChangeDefaultCameraShakerSubscription(subscribe);
|
||||
else
|
||||
ChangeCameraShakerSubscription(_currentCameraShaker, subscribe);
|
||||
}
|
||||
//ObjectShaker type.
|
||||
else if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
if (_objectShaker != null)
|
||||
{
|
||||
if (subscribe)
|
||||
{
|
||||
_objectShaker.OnShakeUpdate += ObjectShaker_OnShakeUpdate;
|
||||
_objectShaker.OnShakingStarted += ObjectShaker_OnShakingStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
_objectShaker.OnShakeUpdate -= ObjectShaker_OnShakeUpdate;
|
||||
_objectShaker.OnShakingStarted -= ObjectShaker_OnShakingStarted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 663365fdc7222f84fa76f2a79859e1f5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 162991
|
||||
packageName: Smooth Camera Shaker
|
||||
packageVersion: 2.12
|
||||
assetPath: Assets/FirstGearGames/SmoothCameraShaker/Scripts/Shakables/ShakableCanvas.cs
|
||||
uploadId: 376379
|
||||
@@ -0,0 +1,366 @@
|
||||
using FirstGearGames.Utilities.Maths;
|
||||
using FirstGearGames.Utilities.Objects;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace FirstGearGames.SmoothCameraShaker
|
||||
{
|
||||
|
||||
|
||||
public class ShakableRigidbody : ShakableBase
|
||||
{
|
||||
#region Types.
|
||||
/// <summary>
|
||||
/// Data about how to update rigidbodies with shakes.
|
||||
/// </summary>
|
||||
private class RigidbodyData
|
||||
{
|
||||
public RigidbodyData(Rigidbody rb)
|
||||
{
|
||||
Rigidbody = rb;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rigidbody on this object.
|
||||
/// </summary>
|
||||
public readonly Rigidbody Rigidbody;
|
||||
/// <summary>
|
||||
/// Direction to multiply position by at random intervals.
|
||||
/// </summary>
|
||||
public float RandomPositionMultiplier { get; private set; } = 1f;
|
||||
/// <summary>
|
||||
/// Sets the value for RandomPositionMultiplier.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetRandomPositionMultiplier(float value)
|
||||
{
|
||||
RandomPositionMultiplier = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Direction to multiply rotation by at random intervals.
|
||||
/// </summary>
|
||||
public float RandomRotationMultiplier { get; private set; } = 1f;
|
||||
/// <summary>
|
||||
/// Sets the value for RandomRotationMultiplier.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetRandomRotationMultiplier(float value)
|
||||
{
|
||||
RandomRotationMultiplier = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Next time to update randomMultipliers.
|
||||
/// </summary>
|
||||
public float NextRandomizeTime { get; private set; } = -1f;
|
||||
/// <summary>
|
||||
/// Sets the value for NextRandomizeTime.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetNextRandomizeTime(float value)
|
||||
{
|
||||
NextRandomizeTime = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Positional values last time shake offsets were received.
|
||||
/// </summary>
|
||||
public Vector3 LastPositional { get; private set; } = Vector3.zero;
|
||||
/// <summary>
|
||||
/// Sets the value for LastPositional.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetLastPositional(Vector3 value)
|
||||
{
|
||||
LastPositional = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Rotational values last time shake offsets were received.
|
||||
/// </summary>
|
||||
public Vector3 LastRotational { get; private set; } = Vector3.zero;
|
||||
/// <summary>
|
||||
/// Sets the value for LastRotational.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetLastRotational(Vector3 value)
|
||||
{
|
||||
LastRotational = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// Multiplier to apply towards position.
|
||||
/// </summary>
|
||||
[Tooltip("Multiplier to apply towards position.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("_positionMultiplier")]
|
||||
private float _positionalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Multipplier to apply towards rotation.
|
||||
/// </summary>
|
||||
[Tooltip("Multipplier to apply towards rotation.")]
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("_rotationMultiplier")]
|
||||
private float _rotationalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Only shake when in view of a camera.
|
||||
/// </summary>
|
||||
[Tooltip("Only shake when in view of a camera.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
private bool _requireInView = true;
|
||||
/// <summary>
|
||||
/// True to find rigidbodies in children too. This allows you to use one ShakableRigidbody on the parent if all children rigidbodies should shake as well.
|
||||
/// </summary>
|
||||
[Tooltip("True to find rigidbodies in children too. This allows you to use one ShakableRigidbody on the parent if all children rigidbodies should shake as well.")]
|
||||
[SerializeField]
|
||||
private bool _includeChildren = false;
|
||||
/// <summary>
|
||||
/// True to ignore the transform this component resides, and only shake children.
|
||||
/// </summary>
|
||||
[Tooltip("True to ignore the transform this component resides, and only shake children.")]
|
||||
[SerializeField]
|
||||
private bool _ignoreSelf = false;
|
||||
/// <summary>
|
||||
/// True to also find inactive children.
|
||||
/// </summary>
|
||||
[Tooltip("True to also find inactive children.")]
|
||||
[SerializeField]
|
||||
private bool _includeInactive = false;
|
||||
/// <summary>
|
||||
/// True to convert forces to local space before applying.
|
||||
/// </summary>
|
||||
[Tooltip("True to convert forces to local space before applying.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
private bool _localizeShake = false;
|
||||
/// <summary>
|
||||
/// True to randomly change force direction. Best used with bulk objects so they do not all shake the same direction.
|
||||
/// </summary>
|
||||
[Tooltip("True to randomly change force direction. Best used with bulk objects so they do not all shake the same direction.")]
|
||||
[SerializeField]
|
||||
private bool _randomizeDirections = true;
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// Data about each rigidbody to shake.
|
||||
/// </summary>
|
||||
private RigidbodyData[] _rbData;
|
||||
/// <summary>
|
||||
/// True if currently in view.
|
||||
/// </summary>
|
||||
private bool _inView = false;
|
||||
/// <summary>
|
||||
/// ObjectShaker used for this object. May be null if not using ObjectShaker type.
|
||||
/// </summary>
|
||||
private ObjectShaker _objectShaker = null;
|
||||
#endregion
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
FirstInitialize();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (_requireInView && _inView)
|
||||
ChangeSubscription(true);
|
||||
else if (!_requireInView)
|
||||
ChangeSubscription(true);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_requireInView && _inView)
|
||||
ChangeSubscription(false);
|
||||
else if (!_requireInView)
|
||||
ChangeSubscription(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use. Should only be completed once.
|
||||
/// </summary>
|
||||
private void FirstInitialize()
|
||||
{
|
||||
//If using ObjectShaker type.
|
||||
if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
_objectShaker = GetComponentInParent<ObjectShaker>();
|
||||
if (_objectShaker == null)
|
||||
{
|
||||
Debug.LogError("ObjectShaker could not be found on or above object " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If not including children.
|
||||
if (!_includeChildren)
|
||||
{
|
||||
Rigidbody rb = GetComponent<Rigidbody>();
|
||||
if (rb == null)
|
||||
{
|
||||
Debug.LogWarning("Rigidbody is empty on " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_rbData = new RigidbodyData[1];
|
||||
_rbData[0] = new RigidbodyData(rb);
|
||||
}
|
||||
//Include children.
|
||||
else
|
||||
{
|
||||
List<Rigidbody> rbs = new List<Rigidbody>();
|
||||
Transforms.GetComponentsInChildren(transform, rbs, !_ignoreSelf, _includeInactive);
|
||||
if (rbs.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("No rigidbodies exist on parent or children of " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_rbData = new RigidbodyData[rbs.Count];
|
||||
for (int i = 0; i < rbs.Count; i++)
|
||||
_rbData[i] = new RigidbodyData(rbs[i]);
|
||||
}
|
||||
|
||||
/* Try to find a renderer. One is required on this object for OnBecameVisible and OnBecameInvisible
|
||||
* to call. If a renderer doesn't exist then add a low cost renderer. */
|
||||
if (_requireInView)
|
||||
{
|
||||
if (GetComponent<Renderer>() == null)
|
||||
{
|
||||
if (Debug.isDebugBuild)
|
||||
Debug.Log("Renderer not found on object. Adding renderer so RequireInView works properly. Added renderer may be smaller than actual object, and sometimes may not be detected as in view. To resolve add your own renderer to the object this script resides.", this);
|
||||
SpriteRenderer r = gameObject.AddComponent<SpriteRenderer>();
|
||||
r.sprite = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region OnShakeUpdate.
|
||||
/// <summary>
|
||||
/// Received every fixed update a shake occurs. Contains the shake values from last update.
|
||||
/// </summary>
|
||||
private void CameraShakerHandler_OnShakeFixedUpdate(ShakeUpdate obj)
|
||||
{
|
||||
ShakeUpdateOccurred(obj);
|
||||
}
|
||||
/// <summary>
|
||||
/// Received every fixed update a shake occurs. Contains the shake values from last update.
|
||||
/// </summary>
|
||||
private void ObjectShaker_OnShakeFixedUpdate(ObjectShaker arg1, ShakeUpdate arg2)
|
||||
{
|
||||
ShakeUpdateOccurred(arg2);
|
||||
}
|
||||
/// <summary>
|
||||
/// Called when a shake update occurs, wether it be from CameraShaker or ObjectShaker.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
private void ShakeUpdateOccurred(ShakeUpdate obj)
|
||||
{
|
||||
if (!_inView && _requireInView)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _rbData.Length; i++)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
//Rigidbody can go null when exiting playmode, and camerashaker may try to send one last update when exiting play mode.
|
||||
if (_rbData[i].Rigidbody == null)
|
||||
return;
|
||||
#endif
|
||||
//Check if random multipliers should be updated.
|
||||
CheckRandomizeRandomers(_rbData[i]);
|
||||
|
||||
//Calculate new offsets.
|
||||
Vector3 newPos = obj.Objects.Position * _rbData[i].RandomPositionMultiplier * _positionalMultiplier;
|
||||
Vector3 newRot = obj.Objects.Rotation * _rbData[i].RandomRotationMultiplier * _rotationalMultiplier;
|
||||
//If to localize force.
|
||||
if (_localizeShake)
|
||||
{
|
||||
newPos = _rbData[i].Rigidbody.transform.TransformDirection(newPos);
|
||||
newRot = _rbData[i].Rigidbody.transform.TransformDirection(newRot);
|
||||
}
|
||||
|
||||
//Apply force.
|
||||
_rbData[i].Rigidbody.AddForce(newPos - _rbData[i].LastPositional, ForceMode.Impulse);
|
||||
_rbData[i].Rigidbody.AddTorque(newRot - _rbData[i].LastRotational, ForceMode.Impulse);
|
||||
//Set last values.
|
||||
_rbData[i].SetLastPositional(newPos);
|
||||
_rbData[i].SetLastRotational(newRot);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Updates random multipliers if they are in need. What a fun name.
|
||||
/// </summary>
|
||||
private void CheckRandomizeRandomers(RigidbodyData data)
|
||||
{
|
||||
if (!_randomizeDirections)
|
||||
return;
|
||||
|
||||
//Becomes true if enough time has passed to make new random multipliers.
|
||||
bool newRandomize = (Time.time > data.NextRandomizeTime);
|
||||
if (newRandomize)
|
||||
data.SetNextRandomizeTime(Time.time + Random.Range(3f, 7f));
|
||||
|
||||
/* If new random multipliers or velocity is zero then randomize multipliers. */
|
||||
if (newRandomize || data.Rigidbody.linearVelocity == Vector3.zero)
|
||||
data.SetRandomPositionMultiplier(Floats.RandomlyFlip(data.RandomPositionMultiplier));
|
||||
if (newRandomize || data.Rigidbody.angularVelocity == Vector3.zero)
|
||||
data.SetRandomRotationMultiplier(Floats.RandomlyFlip(data.RandomRotationMultiplier));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received when visible in any camera.
|
||||
/// </summary>
|
||||
private void OnBecameVisible()
|
||||
{
|
||||
_inView = true;
|
||||
if (_requireInView)
|
||||
ChangeSubscription(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Received when no longer visible in any camera.
|
||||
/// </summary>
|
||||
private void OnBecameInvisible()
|
||||
{
|
||||
_inView = false;
|
||||
if (_requireInView)
|
||||
ChangeSubscription(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the subscription to the camera shaker.
|
||||
/// </summary>
|
||||
/// <param name="subscribe"></param>
|
||||
private void ChangeSubscription(bool subscribe)
|
||||
{
|
||||
//CameraShaker type.
|
||||
if (base.ShakerType == ShakerTypes.CameraShaker)
|
||||
{
|
||||
if (subscribe)
|
||||
CameraShakerHandler.OnAllShakeFixedUpdate += CameraShakerHandler_OnShakeFixedUpdate;
|
||||
else
|
||||
CameraShakerHandler.OnAllShakeFixedUpdate -= CameraShakerHandler_OnShakeFixedUpdate;
|
||||
}
|
||||
//ObjectShaker type.
|
||||
else if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
if (_objectShaker != null)
|
||||
{
|
||||
if (subscribe)
|
||||
_objectShaker.OnShakeFixedUpdate += ObjectShaker_OnShakeFixedUpdate;
|
||||
else
|
||||
_objectShaker.OnShakeFixedUpdate -= ObjectShaker_OnShakeFixedUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5901f943dff13b94693d37f9edb0beb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 162991
|
||||
packageName: Smooth Camera Shaker
|
||||
packageVersion: 2.12
|
||||
assetPath: Assets/FirstGearGames/SmoothCameraShaker/Scripts/Shakables/ShakableRigidbody.cs
|
||||
uploadId: 376379
|
||||
@@ -0,0 +1,362 @@
|
||||
using FirstGearGames.Utilities.Maths;
|
||||
using FirstGearGames.Utilities.Objects;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace FirstGearGames.SmoothCameraShaker
|
||||
{
|
||||
|
||||
|
||||
public class ShakableRigidbody2D : ShakableBase
|
||||
{
|
||||
#region Types.
|
||||
/// <summary>
|
||||
/// Data about how to update rigidbodies with shakes.
|
||||
/// </summary>
|
||||
private class RigidbodyData
|
||||
{
|
||||
public RigidbodyData(Rigidbody2D rb)
|
||||
{
|
||||
Rigidbody = rb;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rigidbody on this object.
|
||||
/// </summary>
|
||||
public readonly Rigidbody2D Rigidbody;
|
||||
/// <summary>
|
||||
/// Direction to multiply position by at random intervals.
|
||||
/// </summary>
|
||||
public float RandomPositionMultiplier { get; private set; } = 1f;
|
||||
/// <summary>
|
||||
/// Sets the value for RandomPositionMultiplier.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetRandomPositionMultiplier(float value)
|
||||
{
|
||||
RandomPositionMultiplier = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Direction to multiply rotation by at random intervals.
|
||||
/// </summary>
|
||||
public float RandomRotationMultiplier { get; private set; } = 1f;
|
||||
/// <summary>
|
||||
/// Sets the value for RandomRotationMultiplier.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetRandomRotationMultiplier(float value)
|
||||
{
|
||||
RandomRotationMultiplier = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Next time to update randomMultipliers.
|
||||
/// </summary>
|
||||
public float NextRandomizeTime { get; private set; } = -1f;
|
||||
/// <summary>
|
||||
/// Sets the value for NextRandomizeTime.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetNextRandomizeTime(float value)
|
||||
{
|
||||
NextRandomizeTime = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Positional values last time shake offsets were received.
|
||||
/// </summary>
|
||||
public Vector2 LastPositional { get; private set; } = Vector2.zero;
|
||||
/// <summary>
|
||||
/// Sets the value for LastPositional.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetLastPositional(Vector2 value)
|
||||
{
|
||||
LastPositional = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Rotational values last time shake offsets were received.
|
||||
/// </summary>
|
||||
public float LastRotational { get; private set; } = 0f;
|
||||
/// <summary>
|
||||
/// Sets the value for LastRotational.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetLastRotational(float value)
|
||||
{
|
||||
LastRotational = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// Multiplier to apply towards position.
|
||||
/// </summary>
|
||||
[Tooltip("Multiplier to apply towards position.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("_positionMultiplier")]
|
||||
private float _positionalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Multipplier to apply towards rotation.
|
||||
/// </summary>
|
||||
[Tooltip("Multipplier to apply towards rotation.")]
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("_rotationMultiplier")]
|
||||
private float _rotationalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Only shake when in view of a camera.
|
||||
/// </summary>
|
||||
[Tooltip("Only shake when in view of a camera.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
private bool _requireInView = true;
|
||||
/// <summary>
|
||||
/// True to find rigidbodies in children too. This allows you to use one ShakableRigidbody on the parent if all children rigidbodies should shake as well.
|
||||
/// </summary>
|
||||
[Tooltip("True to find rigidbodies in children too. This allows you to use one ShakableRigidbody on the parent if all children rigidbodies should shake as well.")]
|
||||
[SerializeField]
|
||||
private bool _includeChildren = false;
|
||||
/// <summary>
|
||||
/// True to ignore the transform this component resides, and only shake children.
|
||||
/// </summary>
|
||||
[Tooltip("True to ignore the transform this component resides, and only shake children.")]
|
||||
[SerializeField]
|
||||
private bool _ignoreSelf = false;
|
||||
/// <summary>
|
||||
/// True to also find inactive children.
|
||||
/// </summary>
|
||||
[Tooltip("True to also find inactive children.")]
|
||||
[SerializeField]
|
||||
private bool _includeInactive = false;
|
||||
/// <summary>
|
||||
/// True to convert forces to local space before applying.
|
||||
/// </summary>
|
||||
[Tooltip("True to convert forces to local space before applying.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
private bool _localizeShake = false;
|
||||
/// <summary>
|
||||
/// True to randomly change force direction. Best used with bulk objects so they do not all shake the same direction.
|
||||
/// </summary>
|
||||
[Tooltip("True to randomly change force direction. Best used with bulk objects so they do not all shake the same direction.")]
|
||||
[SerializeField]
|
||||
private bool _randomizeDirections = true;
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// Data about each rigidbody to shake.
|
||||
/// </summary>
|
||||
private RigidbodyData[] _rbData;
|
||||
/// <summary>
|
||||
/// True if currently in view.
|
||||
/// </summary>
|
||||
private bool _inView = false;
|
||||
/// <summary>
|
||||
/// ObjectShaker used for this object. May be null if not using ObjectShaker type.
|
||||
/// </summary>
|
||||
private ObjectShaker _objectShaker = null;
|
||||
#endregion
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
FirstInitialize();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (_requireInView && _inView)
|
||||
ChangeSubscription(true);
|
||||
else if (!_requireInView)
|
||||
ChangeSubscription(true);
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_requireInView && _inView)
|
||||
ChangeSubscription(false);
|
||||
else if (!_requireInView)
|
||||
ChangeSubscription(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use. Should only be completed once.
|
||||
/// </summary>
|
||||
private void FirstInitialize()
|
||||
{
|
||||
//If using ObjectShaker type.
|
||||
if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
_objectShaker = GetComponentInParent<ObjectShaker>();
|
||||
if (_objectShaker == null)
|
||||
{
|
||||
Debug.LogError("ObjectShaker could not be found on or above object " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If not including children.
|
||||
if (!_includeChildren)
|
||||
{
|
||||
Rigidbody2D rb = GetComponent<Rigidbody2D>();
|
||||
if (rb == null)
|
||||
{
|
||||
Debug.LogWarning("Rigidbody is empty on " + gameObject.name + ". Shakable will not function.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_rbData = new RigidbodyData[1];
|
||||
_rbData[0] = new RigidbodyData(rb);
|
||||
}
|
||||
//Include children.
|
||||
else
|
||||
{
|
||||
List<Rigidbody2D> rbs = new List<Rigidbody2D>();
|
||||
Transforms.GetComponentsInChildren(transform, rbs, !_ignoreSelf, _includeInactive);
|
||||
if (rbs.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("No rigidbodies exist on parent or children of " + gameObject.name + ". Shakable will not function.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_rbData = new RigidbodyData[rbs.Count];
|
||||
for (int i = 0; i < rbs.Count; i++)
|
||||
_rbData[i] = new RigidbodyData(rbs[i]);
|
||||
}
|
||||
|
||||
/* Try to find a renderer. One is required on this object for OnBecameVisible and OnBecameInvisible
|
||||
* to call. If a renderer doesn't exist then add a low cost renderer. */
|
||||
if (_requireInView)
|
||||
{
|
||||
if (GetComponent<Renderer>() == null)
|
||||
{
|
||||
if (Debug.isDebugBuild)
|
||||
Debug.Log("Renderer not found on object. Adding renderer so RequireInView works properly. Added renderer may be smaller than actual object, and sometimes may not be detected as in view. To resolve add your own renderer to the object this script resides.", this);
|
||||
SpriteRenderer r = gameObject.AddComponent<SpriteRenderer>();
|
||||
r.sprite = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region OnShakeUpdates.
|
||||
/// <summary>
|
||||
/// Received every fixed update a shake occurs. Contains the shake values from last update.
|
||||
/// </summary>
|
||||
private void CameraShakerHandler_OnShakeFixedUpdate(ShakeUpdate obj)
|
||||
{
|
||||
ShakeUpdateOccurred(obj);
|
||||
}
|
||||
/// <summary>
|
||||
/// Received every fixed update a shake occurs. Contains the shake values from last update.
|
||||
/// </summary>
|
||||
private void ObjectShaker_OnShakeFixedUpdate(ObjectShaker arg1, ShakeUpdate arg2)
|
||||
{
|
||||
ShakeUpdateOccurred(arg2);
|
||||
}
|
||||
/// <summary>
|
||||
/// Called when a shake update occurs, wether it be from CameraShaker or ObjectShaker.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
private void ShakeUpdateOccurred(ShakeUpdate obj)
|
||||
{
|
||||
if (!_inView && _requireInView)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _rbData.Length; i++)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
//Rigidbody can go null when exiting playmode, and camerashaker may try to send one last update when exiting play mode.
|
||||
if (_rbData[i].Rigidbody == null)
|
||||
return;
|
||||
#endif
|
||||
//Check if random multipliers should be updated.
|
||||
CheckRandomizeRandomers(_rbData[i]);
|
||||
|
||||
//Calculate new offsets.
|
||||
Vector2 newPos = obj.Objects.Position * _rbData[i].RandomPositionMultiplier * _positionalMultiplier;
|
||||
float newRot = obj.Objects.Rotation.z * _rbData[i].RandomRotationMultiplier * _rotationalMultiplier;
|
||||
//If to localize force.
|
||||
if (_localizeShake)
|
||||
newPos = _rbData[i].Rigidbody.transform.TransformDirection(newPos);
|
||||
|
||||
//Apply force.
|
||||
_rbData[i].Rigidbody.AddForce(newPos - _rbData[i].LastPositional, ForceMode2D.Impulse);
|
||||
_rbData[i].Rigidbody.AddTorque(newRot - _rbData[i].LastRotational, ForceMode2D.Impulse);
|
||||
//Set last values.
|
||||
_rbData[i].SetLastPositional(newPos);
|
||||
_rbData[i].SetLastRotational(newRot);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Updates random multipliers if they are in need. What a fun name.
|
||||
/// </summary>
|
||||
private void CheckRandomizeRandomers(RigidbodyData data)
|
||||
{
|
||||
if (!_randomizeDirections)
|
||||
return;
|
||||
|
||||
//Becomes true if enough time has passed to make new random multipliers.
|
||||
bool newRandomize = (Time.time > data.NextRandomizeTime);
|
||||
if (newRandomize)
|
||||
data.SetNextRandomizeTime(Time.time + Random.Range(3f, 7f));
|
||||
|
||||
/* If new random multipliers or velocity is zero then randomize multipliers. */
|
||||
if (newRandomize || data.Rigidbody.linearVelocity == Vector2.zero)
|
||||
data.SetRandomPositionMultiplier(Floats.RandomlyFlip(data.RandomPositionMultiplier));
|
||||
if (newRandomize || data.Rigidbody.angularVelocity == 0f)
|
||||
data.SetRandomRotationMultiplier(Floats.RandomlyFlip(data.RandomRotationMultiplier));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received when visible in any camera.
|
||||
/// </summary>
|
||||
private void OnBecameVisible()
|
||||
{
|
||||
_inView = true;
|
||||
if (_requireInView)
|
||||
ChangeSubscription(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Received when no longer visible in any camera.
|
||||
/// </summary>
|
||||
private void OnBecameInvisible()
|
||||
{
|
||||
_inView = false;
|
||||
if (_requireInView)
|
||||
ChangeSubscription(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the subscription to the camera shaker.
|
||||
/// </summary>
|
||||
/// <param name="subscribe"></param>
|
||||
private void ChangeSubscription(bool subscribe)
|
||||
{
|
||||
//CameraShaker type.
|
||||
if (base.ShakerType == ShakerTypes.CameraShaker)
|
||||
{
|
||||
if (subscribe)
|
||||
CameraShakerHandler.OnAllShakeFixedUpdate += CameraShakerHandler_OnShakeFixedUpdate;
|
||||
else
|
||||
CameraShakerHandler.OnAllShakeFixedUpdate -= CameraShakerHandler_OnShakeFixedUpdate;
|
||||
}
|
||||
//ObjectShaker type.
|
||||
else if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
if (_objectShaker != null)
|
||||
{
|
||||
if (subscribe)
|
||||
_objectShaker.OnShakeFixedUpdate += ObjectShaker_OnShakeFixedUpdate;
|
||||
else
|
||||
_objectShaker.OnShakeFixedUpdate -= ObjectShaker_OnShakeFixedUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58b3fda749163f142b26ea94be1da637
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 162991
|
||||
packageName: Smooth Camera Shaker
|
||||
packageVersion: 2.12
|
||||
assetPath: Assets/FirstGearGames/SmoothCameraShaker/Scripts/Shakables/ShakableRigidbody2D.cs
|
||||
uploadId: 376379
|
||||
@@ -0,0 +1,391 @@
|
||||
using FirstGearGames.Utilities.Maths;
|
||||
using FirstGearGames.Utilities.Objects;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace FirstGearGames.SmoothCameraShaker
|
||||
{
|
||||
|
||||
|
||||
public class ShakableTransform : ShakableBase
|
||||
{
|
||||
#region Types.
|
||||
/// <summary>
|
||||
/// Data about how to update rigidbodies with shakes.
|
||||
/// </summary>
|
||||
private class TransformData
|
||||
{
|
||||
public TransformData(Transform t)
|
||||
{
|
||||
Transform = t;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transform on this object.
|
||||
/// </summary>
|
||||
public readonly Transform Transform;
|
||||
/// <summary>
|
||||
/// Direction to multiply position by when shaking starts.
|
||||
/// </summary>
|
||||
public float RandomPositionMultiplier { get; private set; } = 1f;
|
||||
/// <summary>
|
||||
/// Sets the value for RandomPositionMultiplier.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetRandomPositionMultiplier(float value)
|
||||
{
|
||||
RandomPositionMultiplier = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Direction to multiply rotation by when shaking starts.
|
||||
/// </summary>
|
||||
public float RandomRotationMultiplier { get; private set; } = 1f;
|
||||
/// <summary>
|
||||
/// Sets the value for RandomRotationMultiplier.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetRandomRotationMultiplier(float value)
|
||||
{
|
||||
RandomRotationMultiplier = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Positional values last time shake offsets were received.
|
||||
/// </summary>
|
||||
public Vector3 LastPositional { get; private set; } = Vector3.zero;
|
||||
/// <summary>
|
||||
/// Sets the value for LastPositional.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetLastPositional(Vector3 value)
|
||||
{
|
||||
LastPositional = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Rotational values last time shake offsets were received.
|
||||
/// </summary>
|
||||
public Vector3 LastRotational { get; private set; } = Vector3.zero;
|
||||
/// <summary>
|
||||
/// Sets the value for LastRotational.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetLastRotational(Vector3 value)
|
||||
{
|
||||
LastRotational = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// Multiplier to apply towards position.
|
||||
/// </summary>
|
||||
[Tooltip("Multiplier to apply towards position.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
|
||||
private float _positionalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Multipplier to apply towards rotation.
|
||||
/// </summary>
|
||||
[Tooltip("Multipplier to apply towards rotation.")]
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("_rotationMultiplier")]
|
||||
private float _rotationalMultiplier = 1f;
|
||||
/// <summary>
|
||||
/// Only shake when in view of a camera.
|
||||
/// </summary>
|
||||
[Tooltip("Only shake when in view of a camera.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
private bool _requireInView = true;
|
||||
/// <summary>
|
||||
/// True to find transforms in children too. This allows you to use one ShakableTransform on the parent if all children transforms should shake as well.
|
||||
/// </summary>
|
||||
[Tooltip("True to find transforms in children too. This allows you to use one ShakableTransform on the parent if all children transforms should shake as well.")]
|
||||
[SerializeField]
|
||||
private bool _includeChildren = false;
|
||||
/// <summary>
|
||||
/// True to ignore the transform this component resides, and only shake children.
|
||||
/// </summary>
|
||||
[Tooltip("True to ignore the transform this component resides, and only shake children.")]
|
||||
[SerializeField]
|
||||
private bool _ignoreSelf = false;
|
||||
/// <summary>
|
||||
/// True to also find inactive children.
|
||||
/// </summary>
|
||||
[Tooltip("True to also find inactive children.")]
|
||||
[SerializeField]
|
||||
private bool _includeInactive = false;
|
||||
/// <summary>
|
||||
/// True to convert forces to influence space before applying.
|
||||
/// </summary>
|
||||
[Tooltip("True to convert influence to local space before applying.")]
|
||||
[Space(10f)]
|
||||
[SerializeField]
|
||||
private bool _localizeShake = false;
|
||||
/// <summary>
|
||||
/// True to randomly change influence direction. Best used with bulk objects so they do not all shake the same direction.
|
||||
/// </summary>
|
||||
[Tooltip("True to randomly change influence direction. Best used with bulk objects so they do not all shake the same direction.")]
|
||||
[SerializeField]
|
||||
private bool _randomizeDirections = true;
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// Data about each rigidbody to shake.
|
||||
/// </summary>
|
||||
private TransformData[] _tData;
|
||||
/// <summary>
|
||||
/// True if currently in view.
|
||||
/// </summary>
|
||||
private bool _inView = false;
|
||||
/// <summary>
|
||||
/// ObjectShaker used for this object. May be null if not using ObjectShaker type.
|
||||
/// </summary>
|
||||
private ObjectShaker _objectShaker = null;
|
||||
#endregion
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
FirstInitialize();
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
if (_requireInView && _inView)
|
||||
ChangeSubscription(true);
|
||||
else if (!_requireInView)
|
||||
ChangeSubscription(true);
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
if (_requireInView && _inView)
|
||||
ChangeSubscription(false);
|
||||
else if (!_requireInView)
|
||||
ChangeSubscription(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use. Should only be completed once.
|
||||
/// </summary>
|
||||
private void FirstInitialize()
|
||||
{
|
||||
//If using ObjectShaker type.
|
||||
if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
_objectShaker = GetComponentInParent<ObjectShaker>();
|
||||
if (_objectShaker == null)
|
||||
{
|
||||
Debug.LogError("ObjectShaker could not be found on or above object " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If not including children.
|
||||
if (!_includeChildren)
|
||||
{
|
||||
Transform t = transform;
|
||||
if (t == null)
|
||||
{
|
||||
Debug.LogWarning("Transform is empty on " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_tData = new TransformData[1];
|
||||
_tData[0] = new TransformData(t);
|
||||
}
|
||||
//Include children.
|
||||
else
|
||||
{
|
||||
List<Transform> ts = new List<Transform>();
|
||||
Transforms.GetComponentsInChildren(transform, ts, !_ignoreSelf,_includeInactive);
|
||||
if (ts.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("No transforms exist on parent or children of " + gameObject.name + ". Shakable will be destroyed.", this);
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_tData = new TransformData[ts.Count];
|
||||
for (int i = 0; i < ts.Count; i++)
|
||||
_tData[i] = new TransformData(ts[i]);
|
||||
}
|
||||
|
||||
/* Try to find a renderer. One is required on this object for OnBecameVisible and OnBecameInvisible
|
||||
* to call. If a renderer doesn't exist then add a low cost renderer. */
|
||||
if (_requireInView)
|
||||
{
|
||||
if (GetComponent<Renderer>() == null)
|
||||
{
|
||||
if (Debug.isDebugBuild)
|
||||
Debug.Log("Renderer not found on object. Adding renderer so RequireInView works properly. Added renderer may be smaller than actual object, and sometimes may not be detected as in view. To resolve add your own renderer to the object this script resides.", this);
|
||||
SpriteRenderer r = gameObject.AddComponent<SpriteRenderer>();
|
||||
r.sprite = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region OnShakeUpdate.
|
||||
/// <summary>
|
||||
/// Received when shaking starts when previously stopped on all Shakers.
|
||||
/// </summary>
|
||||
private void CameraShakerHandler_OnAllShakingStarted()
|
||||
{
|
||||
RandomizeDirections();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received when shaking starts when previously stopped on all Shakers.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
private void ObjectShaker_OnShakingStarted(ObjectShaker obj)
|
||||
{
|
||||
RandomizeDirections();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received every fixed update a shake occurs. Contains the shake values from last update.
|
||||
/// </summary>
|
||||
private void CameraShakerHandler_OnShakeUpdate(ShakeUpdate obj)
|
||||
{
|
||||
ShakeUpdateOccurred(obj);
|
||||
}
|
||||
/// <summary>
|
||||
/// Received every fixed update a shake occurs. Contains the shake values from last update.
|
||||
/// </summary>
|
||||
private void ObjectShaker_OnShakeUpdate(ObjectShaker arg1, ShakeUpdate arg2)
|
||||
{
|
||||
ShakeUpdateOccurred(arg2);
|
||||
}
|
||||
/// <summary>
|
||||
/// Called when a shake update occurs, wether it be from CameraShaker or ObjectShaker.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
private void ShakeUpdateOccurred(ShakeUpdate obj)
|
||||
{
|
||||
if (!_inView && _requireInView)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _tData.Length; i++)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
//Transform can go null when exiting playmode, and shaker may try to send one last update when exiting play mode.
|
||||
if (_tData[i].Transform == null)
|
||||
return;
|
||||
#endif
|
||||
//Calculate new offsets.
|
||||
Vector3 newPos = obj.Objects.Position * _tData[i].RandomPositionMultiplier * _positionalMultiplier;
|
||||
Vector3 newRot = obj.Objects.Rotation * _tData[i].RandomRotationMultiplier * _rotationalMultiplier;
|
||||
//If to localize force.
|
||||
if (_localizeShake)
|
||||
{
|
||||
newPos = _tData[i].Transform.transform.TransformDirection(newPos);
|
||||
newRot = _tData[i].Transform.transform.TransformDirection(newRot);
|
||||
}
|
||||
|
||||
//Apply changes.
|
||||
_tData[i].Transform.localPosition += (newPos - _tData[i].LastPositional);
|
||||
_tData[i].Transform.localEulerAngles += (newRot - _tData[i].LastRotational);
|
||||
//Set last values.
|
||||
_tData[i].SetLastPositional(newPos);
|
||||
_tData[i].SetLastRotational(newRot);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Updates random multipliers for all transform datas.
|
||||
/// </summary>
|
||||
private void RandomizeDirections()
|
||||
{
|
||||
if (!_randomizeDirections)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _tData.Length; i++)
|
||||
RandomizeDirections(_tData[i]);
|
||||
}
|
||||
/// <summary>
|
||||
/// Updates random multipliers for data.
|
||||
/// </summary>
|
||||
private void RandomizeDirections(TransformData data)
|
||||
{
|
||||
if (!_randomizeDirections)
|
||||
return;
|
||||
|
||||
data.SetRandomPositionMultiplier(Floats.RandomlyFlip(data.RandomPositionMultiplier));
|
||||
data.SetRandomRotationMultiplier(Floats.RandomlyFlip(data.RandomRotationMultiplier));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received when visible in any camera.
|
||||
/// </summary>
|
||||
protected virtual void OnBecameVisible()
|
||||
{
|
||||
_inView = true;
|
||||
if (_requireInView)
|
||||
ChangeSubscription(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Received when no longer visible in any camera.
|
||||
/// </summary>
|
||||
protected virtual void OnBecameInvisible()
|
||||
{
|
||||
_inView = false;
|
||||
if (_requireInView)
|
||||
ChangeSubscription(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the subscription to the camera shaker.
|
||||
/// </summary>
|
||||
/// <param name="subscribe"></param>
|
||||
private void ChangeSubscription(bool subscribe)
|
||||
{
|
||||
/* Must subscribe to starting so that random directions
|
||||
* can be reset before a shake begins. */
|
||||
|
||||
//CameraShaker type.
|
||||
if (base.ShakerType == ShakerTypes.CameraShaker)
|
||||
{
|
||||
if (subscribe)
|
||||
{
|
||||
CameraShakerHandler.OnAllShakeUpdate += CameraShakerHandler_OnShakeUpdate;
|
||||
CameraShakerHandler.OnAllShakingStarted += CameraShakerHandler_OnAllShakingStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
CameraShakerHandler.OnAllShakeUpdate -= CameraShakerHandler_OnShakeUpdate;
|
||||
CameraShakerHandler.OnAllShakingStarted -= CameraShakerHandler_OnAllShakingStarted;
|
||||
}
|
||||
}
|
||||
//ObjectShaker type.
|
||||
else if (base.ShakerType == ShakerTypes.ObjectShaker)
|
||||
{
|
||||
if (_objectShaker != null)
|
||||
{
|
||||
if (subscribe)
|
||||
{
|
||||
_objectShaker.OnShakeUpdate += ObjectShaker_OnShakeUpdate;
|
||||
_objectShaker.OnShakingStarted += ObjectShaker_OnShakingStarted;
|
||||
/* If already shaking then randomize directions.
|
||||
* This can occur when ObjectShaker has a ShakeOnEnable
|
||||
* shake and is active before this shakable. */
|
||||
if (_objectShaker.Shaking)
|
||||
RandomizeDirections();
|
||||
}
|
||||
else
|
||||
{
|
||||
_objectShaker.OnShakeUpdate -= ObjectShaker_OnShakeUpdate;
|
||||
_objectShaker.OnShakingStarted -= ObjectShaker_OnShakingStarted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9d4107aad3b3544da23b3f86c3f2d0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 162991
|
||||
packageName: Smooth Camera Shaker
|
||||
packageVersion: 2.12
|
||||
assetPath: Assets/FirstGearGames/SmoothCameraShaker/Scripts/Shakables/ShakableTransform.cs
|
||||
uploadId: 376379
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace FirstGearGames.SmoothCameraShaker
|
||||
{
|
||||
/// <summary>
|
||||
/// ShakableTransform2D is currently the exact same as ShakableTransform. Using inheritance for now should I want to expand upon ShakableTransform2D later.
|
||||
/// </summary>
|
||||
public class ShakableTransform2D : ShakableTransform
|
||||
{
|
||||
protected override void Awake() { base.Awake(); }
|
||||
protected override void OnEnable() { base.OnEnable(); }
|
||||
protected override void OnDisable() { base.OnDisable(); }
|
||||
protected override void OnBecameInvisible() { base.OnBecameInvisible(); }
|
||||
protected override void OnBecameVisible() { base.OnBecameVisible(); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1668e20ecaba69547a8a160014c5640b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 162991
|
||||
packageName: Smooth Camera Shaker
|
||||
packageVersion: 2.12
|
||||
assetPath: Assets/FirstGearGames/SmoothCameraShaker/Scripts/Shakables/ShakableTransform2D.cs
|
||||
uploadId: 376379
|
||||
Reference in New Issue
Block a user