using System.Collections.Generic;
using UnityEngine;
namespace Invector.vEventSystems
{
public interface vIAnimatorStateInfoController
{
vAnimatorStateInfos animatorStateInfos { get; }
}
public static class vIAnimatorStateInfoHelper
{
///
/// Register all listener to listener
///
///
public static void Register(this vIAnimatorStateInfoController animatorStateInfos)
{
if (animatorStateInfos.isValid())
{
animatorStateInfos.animatorStateInfos.RegisterListener();
}
}
///
/// Remove all listener from
///
///
public static void UnRegister(this vIAnimatorStateInfoController animatorStateInfos)
{
if (animatorStateInfos.isValid())
{
animatorStateInfos.animatorStateInfos.RemoveListener();
}
}
///
/// Check if is valid
///
///
///
public static bool isValid(this vIAnimatorStateInfoController animatorStateInfos)
{
return animatorStateInfos != null && animatorStateInfos.animatorStateInfos != null && animatorStateInfos.animatorStateInfos.animator != null;
}
}
[System.Serializable]
public class vAnimatorStateInfos
{
public bool debug;
public Animator animator;
public vAnimatorStateInfos(Animator animator)
{
this.animator = animator;
Init();
}
public void Init()
{
if (animator)
{
stateInfos = new vStateInfo[animator.layerCount];
for (int i = 0; i < stateInfos.Length; i++)
{
stateInfos[i] = new vStateInfo(i);
}
}
}
public void RegisterListener()
{
var bhv = animator.GetBehaviours();
for (int i = 0; i < bhv.Length; i++)
{
bhv[i].RemoveStateInfoListener(this);
bhv[i].AddStateInfoListener(this);
}
if (debug)
{
Debug.Log($"Listeners Registered", animator);
}
}
public void RemoveListener()
{
if (animator)
{
var bhv = animator.GetBehaviours();
for (int i = 0; i < bhv.Length; i++)
{
bhv[i].RemoveStateInfoListener(this);
}
if (debug)
{
Debug.Log($"Listeners Removed", animator);
}
}
}
public vStateInfo[] stateInfos = new vStateInfo[0];
[System.Serializable]
public class vStateInfo
{
public int layer;
public int shortPathHash;
public float normalizedTime;
public List tags = new List();
public vStateInfo(int layer)
{
this.layer = layer;
}
}
///
/// Add tag to the layer
///
/// Tag
/// Animator layer
public void AddStateInfo(string tag, int layer)
{
if (stateInfos.Length > 0 && layer < stateInfos.Length)
{
vStateInfo info = stateInfos[layer];
info.tags.Add(tag);
info.shortPathHash = 0;
info.normalizedTime = 0;
}
if (debug)
{
Debug.Log($"Add tag : {tag},in the animator layer :{layer}", animator);
}
}
///
/// Uptade State info
///
/// state layer
/// state normalizedTime
/// state fullPathHash
public void UpdateStateInfo(int layer, float normalizedTime, int fullPathHash)
{
if (stateInfos.Length > 0 && layer < stateInfos.Length)
{
vStateInfo info = stateInfos[layer];
info.normalizedTime = normalizedTime;
info.shortPathHash = fullPathHash;
}
}
///
/// Remove Tag of the layer
///
/// Tag
/// Animator layer
public void RemoveStateInfo(string tag, int layer)
{
if (stateInfos.Length > 0 && layer < stateInfos.Length)
{
vStateInfo info = stateInfos[layer];
if (info.tags.Contains(tag))
{
info.tags.Remove(tag);
if (info.tags.Count == 0)
{
info.shortPathHash = 0;
info.normalizedTime = 0;
}
if (debug)
{
Debug.Log($"Remove tag : {tag}, in the animator layer :{layer}", animator);
}
}
}
}
///
/// Check If StateInfo list contains tag
///
/// tag to check
///
public bool HasTag(string tag)
{
return System.Array.Exists(stateInfos, info => info.tags.Contains(tag));
}
///
/// Check if All tags in in StateInfo List
///
/// tags to check
///
public bool HasAllTags(params string[] tags)
{
var has = tags.Length > 0 ? true : false;
for (int i = 0; i < tags.Length; i++)
{
if (!HasTag(tags[i]))
{
has = false;
break;
}
}
return has;
}
///
/// Check if StateInfo List Contains any tag
///
/// tags to check
///
public bool HasAnyTag(params string[] tags)
{
var has = false;
for (int i = 0; i < tags.Length; i++)
{
if (HasTag(tags[i]))
{
has = true;
break;
}
}
return has;
}
///
/// Get current animator state info using tag
///
/// tag
/// if tag exit return AnimatorStateInfo? else return null
public vStateInfo GetStateInfoUsingTag(string tag)
{
return System.Array.Find(stateInfos, info => info.tags.Contains(tag));
}
public float GetCurrentNormalizedTime(int layer)
{
if (stateInfos.Length > 0 && layer < stateInfos.Length)
{
vStateInfo info = stateInfos[layer];
return info.normalizedTime;
}
return 0;
}
}
}