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(); } } }