Created
January 21, 2017 07:37
-
-
Save iwashihead/9204fd3d5d51adff5dfc61b84f019a86 to your computer and use it in GitHub Desktop.
汎用シェイク処理
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
using Random = UnityEngine.Random; | |
namespace hoge | |
{ | |
/// <summary> | |
/// シェイク処理 | |
/// </summary> | |
public class Shaker : IDisposable | |
{ | |
/// <summary> | |
/// シェイク構造体 | |
/// </summary> | |
private struct ShakeParam | |
{ | |
/// <summary>シェイク中かどうか</summary> | |
public bool IsShake; | |
/// <summary>減衰率</summary> | |
public EasingUtility.EasingType DecayType; | |
/// <summary>シェイクの開始時間</summary> | |
public float StartTime; | |
/// <summary>シェイクにかける時間</summary> | |
public float Duration; | |
/// <summary>シェイク量</summary> | |
public float RandomAmount; | |
} | |
/// <summary> | |
/// 2D用のシェイクかどうか. | |
/// Trueの場合、Zは変化せずXYのみ変化します. | |
/// </summary> | |
public bool Is2D { get; set; } | |
/// <summary> | |
/// ローカルポジションかどうか | |
/// </summary> | |
public bool IsLocal { get; set; } | |
/// <summary> | |
/// シェイクのターゲット | |
/// </summary> | |
public Transform Target { get; set; } | |
/// <summary> | |
/// シェイクパラメーター | |
/// </summary> | |
private ShakeParam _shakeParam = default(ShakeParam); | |
/// <summary> | |
/// ターゲットの初期位置 | |
/// IsLocalがTrueならlocalPositionが、FalseならPositionが代入されます | |
/// </summary> | |
private Vector3 _initializePos = Vector3.zero; | |
#region Constractor | |
/// <summary> | |
/// 2D用コンストラクタ | |
/// </summary> | |
/// <param name="target"></param> | |
public Shaker(RectTransform target) | |
{ | |
Is2D = true; | |
IsLocal = true; | |
Target = target; | |
_initializePos = IsLocal ? Target.localPosition : Target.position; | |
} | |
/// <summary> | |
/// 3D用コンストラクタ | |
/// </summary> | |
/// <param name="target"></param> | |
public Shaker(Transform target) | |
{ | |
Is2D = false; | |
IsLocal = true; | |
Target = target; | |
_initializePos = IsLocal ? Target.localPosition : Target.position; | |
} | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
/// <param name="is2D"></param> | |
/// <param name="isLocal"></param> | |
/// <param name="target"></param> | |
public Shaker(bool is2D, bool isLocal, Transform target) | |
{ | |
Is2D = is2D; | |
IsLocal = isLocal; | |
Target = target; | |
_initializePos = IsLocal ? Target.localPosition : Target.position; | |
} | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
/// <param name="is2D"></param> | |
/// <param name="isLocal"></param> | |
/// <param name="target"></param> | |
/// <param name="initialPos"></param> | |
public Shaker(bool is2D, bool isLocal, Transform target, Vector3 initialPos) | |
{ | |
Is2D = is2D; | |
IsLocal = isLocal; | |
Target = target; | |
_initializePos = initialPos; | |
} | |
#endregion | |
#region IDisposable | |
/// <summary> | |
/// 破棄処理 | |
/// </summary> | |
public void Dispose() | |
{ | |
Memory.Delete(ref _shakeParam); | |
Memory.Delete(ref _initializePos); | |
Memory.Delete(Target); | |
} | |
#endregion | |
#region Public Method | |
/// <summary> | |
/// シェイクを開始します | |
/// </summary> | |
/// <param name="duration">シェイクさせる時間</param> | |
/// <param name="amount">シェイク量(この値からランダムにシェイクします)</param> | |
/// <param name="decayType">シェイク量の減衰タイプ</param> | |
public void SetShake(float duration, float amount, EasingUtility.EasingType decayType = EasingUtility.EasingType.Linear) | |
{ | |
_shakeParam = new ShakeParam() | |
{ | |
IsShake = true, //Shake開始 | |
StartTime = Time.time, | |
Duration = duration, | |
RandomAmount = amount | |
}; | |
} | |
/// <summary> | |
/// シェイクを中止します | |
/// </summary> | |
public void CancelShake() | |
{ | |
_shakeParam.IsShake = false; | |
if (IsLocal) | |
{ | |
Target.localPosition = _initializePos; | |
} | |
else | |
{ | |
Target.position = _initializePos; | |
} | |
} | |
/// <summary> | |
/// シェイクの更新を行います | |
/// MonoのUpdate、もしくはLateUpdateでよびだしてください | |
/// </summary> | |
public void UpdateShake() | |
{ | |
if (Target == null) return; | |
if (_shakeParam.IsShake == false) return; | |
var elapsedTime = Time.time - _shakeParam.StartTime; | |
if (elapsedTime >= _shakeParam.Duration) | |
{ | |
// Shake終了. | |
_shakeParam.IsShake = false; | |
if (IsLocal) | |
{ | |
Target.localPosition = _initializePos; | |
} | |
else | |
{ | |
Target.position = _initializePos; | |
} | |
} | |
else | |
{ | |
/* Shake量の計算 */ | |
// 経過時間から進捗率を0~1で計算. | |
var progress = Mathf.Clamp01(elapsedTime / _shakeParam.Duration); | |
// 進捗率にイージングを加味したシェイクの減衰率を計算. | |
var decayRate = EasingUtility.GetEasingFunc(EasingUtility.EasingType.EaseInCubic)(1f, 0f, progress); | |
// 減衰率を加味したシェイク量をランダムで取得. | |
Vector3 shakeAmount; | |
if (Is2D) | |
{ | |
shakeAmount = Random.insideUnitCircle * _shakeParam.RandomAmount * decayRate; | |
} | |
else | |
{ | |
shakeAmount = Random.insideUnitSphere * _shakeParam.RandomAmount * decayRate; | |
} | |
// シェイクの実行 | |
if (IsLocal) | |
{ | |
Target.localPosition = _initializePos + shakeAmount; | |
} | |
else | |
{ | |
Target.position = _initializePos + shakeAmount; | |
} | |
} | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment