namespace UnityHelpers.Utils
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using Core.Extension;
using UnityEngine;
///
/// Maps & manages an enum parameter to bool Animator parameters.
///
/// Specific Enum being managed.
[DataContract]
public sealed class AnimatorEnumStateMachine
where T : struct, IConvertible, IComparable, IFormattable // This is as close as we can get to saying where T : Enum (https://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum)
{
private static readonly T[] Values = Enum.GetValues(typeof(T)).OfType().ToArray();
[JsonIgnore]
[IgnoreDataMember]
private readonly HashSet _availableBools = new HashSet();
[JsonIgnore]
[IgnoreDataMember]
public readonly Animator Animator;
[JsonIgnore]
[IgnoreDataMember]
private T _value;
[DataMember]
[JsonInclude]
public T Value
{
get { return _value; }
set
{
foreach (T possibleValue in Values)
{
string valueName = possibleValue.ToString(CultureInfo.InvariantCulture);
if (_availableBools.Contains(valueName))
{
Animator.SetBool(valueName, Equals(value, possibleValue));
}
}
_value = value;
}
}
[DataMember]
[JsonInclude]
private string Type => typeof(T).Name;
public AnimatorEnumStateMachine(Animator animator, T defaultValue = default(T))
{
if (animator == null)
{
throw new ArgumentNullException(nameof(animator));
}
Animator = animator;
foreach (AnimatorControllerParameter parameter in Animator.parameters)
{
switch (parameter.type)
{
case AnimatorControllerParameterType.Bool:
case AnimatorControllerParameterType.Trigger:
_availableBools.Add(parameter.name);
continue;
default:
continue;
}
}
_value = defaultValue;
}
public override string ToString()
{
return this.ToJson();
}
}
}