using System.Collections.Generic; using UnityEngine; namespace FIMSpace.Basics { /// /// FM: Basic class for holding animation clips as hashes inside dictionary and with some other handy methods /// Add your animation clips with fAnimationClip.AddClip(animator, Idle) then use it by fAnimationClip["Idle"] /// public class FAnimationClips : Dictionary { /// Reference to Unity's Animator component public readonly Animator Animator; /// Lastest crossfaded from code animation clip name public string CurrentAnimation { get; private set; } /// Previously crossfaded from code animation clip name public string PreviousAnimation { get; private set; } public int Layer = 0; /// /// ADD ANIMATION CLIPS USING - AddClip() - method !!! /// public FAnimationClips(Animator animator) { this.Animator = animator; CurrentAnimation = ""; PreviousAnimation = ""; } /// /// Checking if inside animator clipName state exist and with 'exactClipName' false it will check all variants of clipName, uppercase / lowercase etc. /// public void Add(string clipName, bool exactClipName = false) { AddClip(clipName, exactClipName); } /// /// Checking if inside animator clipName state exist and with 'exactClipName' false it will check all variants of clipName, uppercase / lowercase etc. /// public void AddClip(string clipName, bool exactClipName = false) { AddClip(Animator, clipName, exactClipName); } /// /// Checking if inside animator clipName state exist and with 'exactClipName' false it will check all variants of clipName, uppercase / lowercase etc. /// public void AddClip(Animator animator, string clipName, bool exactClipName = false) { if (!animator) { Debug.LogError("No animator!"); return; } string existing = ""; if (!exactClipName) // Checking if animation state exists with different variants for clipName word { if (FAnimatorMethods.StateExists(animator, clipName, Layer)) existing = clipName; else if (FAnimatorMethods.StateExists(animator, FStringMethods.CapitalizeFirstLetter(clipName))) existing = FStringMethods.CapitalizeFirstLetter(clipName); else if (FAnimatorMethods.StateExists(animator, clipName.ToLower(), Layer)) existing = clipName.ToLower(); else if (FAnimatorMethods.StateExists(animator, clipName.ToUpper(), Layer)) existing = clipName.ToUpper(); } else // Checking if state with provided exact name exists inside animator { if (FAnimatorMethods.StateExists(animator, clipName, Layer)) existing = clipName; } if (existing == "") { Debug.LogWarning("Clip with name " + clipName + " not exists in animator from game object " + animator.gameObject.name); } else // Adding clip hash to dictionary if it exists inside animator { if (!ContainsKey(clipName)) Add(clipName, Animator.StringToHash(existing)); } } /// /// Transitioning to choosed animation by dictionary /// public void CrossFadeInFixedTime(string clip, float transitionTime = 0.25f, float timeOffset = 0f, bool startOver = false) { if (this.ContainsKey(clip)) { RefreshClipMemory(clip); if (startOver) Animator.CrossFadeInFixedTime(this[clip], transitionTime, Layer, timeOffset); else if (!IsPlaying(clip)) Animator.CrossFadeInFixedTime(this[clip], transitionTime, Layer, timeOffset); } } /// /// Transitioning to choosed animation by dictionary /// public void CrossFade(string clip, float transitionTime = 0.25f, float timeOffset = 0f, bool startOver = false) { if (this.ContainsKey(clip)) { RefreshClipMemory(clip); if (startOver) Animator.CrossFade(this[clip], transitionTime, Layer, timeOffset); else if (!IsPlaying(clip)) Animator.CrossFade(this[clip], transitionTime, Layer, timeOffset); } } /// /// Storing lately and currently played clip in variables /// private void RefreshClipMemory(string name) { if (name != CurrentAnimation) { PreviousAnimation = CurrentAnimation; CurrentAnimation = name; } } /// /// Changing float parameter value smoothly (when speed value about 10, 60 is instant) /// public void SetFloat(string parameter, float value = 0f, float deltaSpeed = 60f) { float newValue = Animator.GetFloat(parameter); if (deltaSpeed >= 60f) newValue = value; else newValue = FLogicMethods.FLerp(newValue, value, Time.deltaTime * deltaSpeed); Animator.SetFloat(parameter, newValue); } /// /// Changing float parameter value smoothly (when speed value about 10, 60 is instant) /// public void SetFloatUnscaledDelta(string parameter, float value = 0f, float deltaSpeed = 60f) { float newValue = Animator.GetFloat(parameter); if (deltaSpeed >= 60f) newValue = value; else newValue = FLogicMethods.FLerp(newValue, value, Time.unscaledDeltaTime * deltaSpeed); Animator.SetFloat(parameter, newValue); } /// /// If animator is truly playing clip with given string id (added by you using clips.AddClip(name) ) /// internal bool IsPlaying(string clip) { AnimatorStateInfo info; if (Animator.IsInTransition(Layer)) { info = Animator.GetNextAnimatorStateInfo(Layer); if (info.shortNameHash == this[clip]) return true; } else { info = Animator.GetCurrentAnimatorStateInfo(Layer); if (info.shortNameHash == this[clip]) return true; } return false; } } public class FAnimator { /// Reference to Unity's Animator component public readonly Animator Animator; /// Lastest crossfaded from code animation clip name public string CurrentAnimation { get; private set; } /// Previously crossfaded from code animation clip name public string PreviousAnimation { get; private set; } public int Layer { get; private set; } /// /// ADD ANIMATION CLIPS USING - AddClip() - method !!! /// public FAnimator(Animator animator, int layer = 0) { this.Animator = animator; CurrentAnimation = ""; PreviousAnimation = ""; Layer = layer; } /// /// Checking if inside animator clipName state exist and with 'exactClipName' false it will check all variants of clipName, uppercase / lowercase etc. /// public bool ContainsClip(string clipName, bool exactClipName = false) { if (!Animator) { Debug.LogError("No animator!"); return false; } string existing = ""; if (!exactClipName) // Checking if animation state exists with different variants for clipName word { if (FAnimatorMethods.StateExists(Animator, clipName, Layer)) existing = clipName; else if (FAnimatorMethods.StateExists(Animator, FStringMethods.CapitalizeFirstLetter(clipName))) existing = FStringMethods.CapitalizeFirstLetter(clipName); else if (FAnimatorMethods.StateExists(Animator, clipName.ToLower(), Layer)) existing = clipName.ToLower(); else if (FAnimatorMethods.StateExists(Animator, clipName.ToUpper(), Layer)) existing = clipName.ToUpper(); } else // Checking if state with provided exact name exists inside animator { if (FAnimatorMethods.StateExists(Animator, clipName, Layer)) existing = clipName; } if (existing == "") { Debug.LogWarning("Clip with name " + clipName + " not exists in animator from game object " + Animator.gameObject.name); return false; } else return true; } /// /// Transitioning to choosed animation by dictionary /// public void CrossFadeInFixedTime(string clip, float transitionTime = 0.25f, float timeOffset = 0f, bool startOver = false) { RefreshClipMemory(clip); if (startOver) Animator.CrossFadeInFixedTime(clip, transitionTime, Layer, timeOffset); else if (!IsPlaying(clip)) Animator.CrossFadeInFixedTime(clip, transitionTime, Layer, timeOffset); } /// /// Transitioning to choosed animation by dictionary /// public void CrossFade(string clip, float transitionTime = 0.25f, float timeOffset = 0f, bool startOver = false) { RefreshClipMemory(clip); if (startOver) Animator.CrossFade(clip, transitionTime, Layer, timeOffset); else if (!IsPlaying(clip)) Animator.CrossFade(clip, transitionTime, Layer, timeOffset); } /// /// Storing lately and currently played clip in variables /// private void RefreshClipMemory(string name) { if (name != CurrentAnimation) { PreviousAnimation = CurrentAnimation; CurrentAnimation = name; } } /// /// Changing float parameter value smoothly (when speed value about 10, 60 is instant) /// public void SetFloat(string parameter, float value = 0f, float deltaSpeed = 60f) { float newValue = Animator.GetFloat(parameter); if (deltaSpeed >= 60f) newValue = value; else newValue = FLogicMethods.FLerp(newValue, value, Time.deltaTime * deltaSpeed); Animator.SetFloat(parameter, newValue); } /// /// Changing float parameter value smoothly (when speed value about 10, 60 is instant) /// public void SetFloatUnscaledDelta(string parameter, float value = 0f, float deltaSpeed = 60f) { float newValue = Animator.GetFloat(parameter); if (deltaSpeed >= 60f) newValue = value; else newValue = FLogicMethods.FLerp(newValue, value, Time.unscaledDeltaTime * deltaSpeed); Animator.SetFloat(parameter, newValue); } /// /// If animator is truly playing clip with given string id (added by you using clips.AddClip(name) ) /// internal bool IsPlaying(string clip) { AnimatorStateInfo info; if (Animator.IsInTransition(Layer)) { info = Animator.GetNextAnimatorStateInfo(Layer); if (info.shortNameHash == Animator.StringToHash(clip) ) return true; } else { info = Animator.GetCurrentAnimatorStateInfo(Layer); if (info.shortNameHash == Animator.StringToHash(clip)) return true; } return false; } } }