Last active
January 30, 2017 17:05
-
-
Save HilariousCow/c85047a5044eca036607069cf32703a0 to your computer and use it in GitHub Desktop.
Some Animator extensions I use to reduce the clutter involved in setting up a hashed call to an animator parameter
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 System.Collections; | |
[Serializable] | |
public class AnimParam | |
{ | |
private readonly int _hashed;//a cached off version of the hashed string | |
private readonly string _paramName;//don't really need but good for debug? | |
private readonly Animator _anim; | |
private float _floatValue; | |
public float FloatValue { | |
get | |
{ | |
return _anim.GetFloat(_hashed); | |
} | |
set | |
{ | |
SetFloat(value); | |
} | |
} | |
private bool _boolValue; | |
public bool BoolValue | |
{ | |
get | |
{ | |
return _anim.GetBool(_hashed); | |
} | |
set | |
{ | |
SetBool(value); | |
} | |
} | |
private int _intValue; | |
public int IntValue | |
{ | |
get | |
{ | |
return _anim.GetInteger(_hashed); | |
} | |
set | |
{ | |
SetInt(value); | |
} | |
} | |
public string ParamName | |
{ | |
get { return _paramName; } | |
} | |
public int Hashed | |
{ | |
get { return _hashed; } | |
} | |
public AnimParam(Animator animator, string param) | |
{ | |
if (animator == null) Debug.LogError("Animator is null"); | |
_anim = animator; | |
_paramName = param; | |
_hashed = Animator.StringToHash(param); | |
} | |
public void SetFloat(float val) | |
{ | |
_floatValue = val; | |
if (_anim.isActiveAndEnabled) | |
{ | |
_anim.SetFloat(Hashed, val); | |
} | |
} | |
public void SetBool(bool val) | |
{ | |
_boolValue = val; | |
if (_anim.isActiveAndEnabled) | |
{ | |
_anim.SetBool(Hashed, val); | |
} | |
} | |
public void SetInt(int val) | |
{ | |
_intValue = val; | |
if (_anim.isActiveAndEnabled) | |
{ | |
_anim.SetInteger(Hashed, val); | |
} | |
} | |
public void SetTrigger() | |
{ | |
if (_anim.isActiveAndEnabled) | |
{ | |
_anim.SetTrigger(Hashed); | |
} | |
} | |
public void ResetTrigger() | |
{ | |
if (_anim.isActiveAndEnabled) | |
{ | |
_anim.ResetTrigger(Hashed); | |
} | |
} | |
public override string ToString() | |
{ | |
return _paramName; | |
} | |
} | |
//useful for setting up 3 parameters for each axis of a vector | |
[Serializable] | |
public class AnimParam3 | |
{ | |
private readonly int _hashedX; | |
private readonly int _hashedY; | |
private readonly int _hashedZ; | |
private readonly string _paramName;//don't really need but good for debug? | |
private readonly Animator _anim; | |
private Vector3 _vectorValue; | |
public Vector3 VectorValue | |
{ | |
get { return new Vector3(_anim.GetFloat(_hashedX), _anim.GetFloat(_hashedY), _anim.GetFloat(_hashedZ)); } | |
set | |
{ | |
SetVector(value); | |
} | |
} | |
public static string GetXStringForParam(string param) { return param + "X"; } | |
public static string GetYStringForParam(string param) { return param + "Y"; } | |
public static string GetZStringForParam(string param) { return param + "Z"; } | |
public string XString { get { return GetXStringForParam(_paramName); } } | |
public string YString { get { return GetYStringForParam(_paramName); } } | |
public string ZString { get { return GetZStringForParam(_paramName); } } | |
public AnimParam3(Animator animator, string param) | |
{ | |
if(animator == null) Debug.LogError("Animator is null"); | |
_anim = animator; | |
_paramName = param; | |
_hashedX = Animator.StringToHash(XString); | |
_hashedY = Animator.StringToHash(YString); | |
_hashedZ = Animator.StringToHash(ZString); | |
} | |
public void SetVector(Vector3 vector3) | |
{ | |
_vectorValue = vector3; | |
_anim.SetFloat(_hashedX,vector3.x ); | |
_anim.SetFloat(_hashedY,vector3.y ); | |
_anim.SetFloat(_hashedZ,vector3.z ); | |
} | |
public override string ToString() | |
{ | |
return _paramName; | |
} | |
} | |
//useful for eulers. currently only dues pitch/yaw since it's common to not want Roll | |
//also sets the angle magnitude of the pitch/yaw | |
[Serializable] | |
public class AnimParamPitchYaw | |
{ | |
private readonly int _hashedPitch; | |
private readonly int _hashedYaw; | |
private readonly int _hashedMagnitude; | |
private readonly string _paramName;//don't really need but good for debug? | |
private readonly Animator _anim; | |
[SerializeField] | |
private Vector2 _vectorValue; | |
public Vector2 VectorValue | |
{ | |
get { return new Vector2(_anim.GetFloat(_hashedPitch), _anim.GetFloat(_hashedYaw)); } | |
set | |
{ | |
SetPitchYaw(value); | |
} | |
} | |
public static string GetPitchStringForParam(string param) { return param + "Pitch"; } | |
public static string GetYawStringForParam(string param) { return param + "Yaw"; } | |
public static string GetMagnitudeStringForParam(string param) { return param + "Magnitude"; } | |
public string PitchString { get { return GetPitchStringForParam(_paramName); } } | |
public string YawString { get { return GetYawStringForParam(_paramName); } } | |
public string MagnitudeString { get { return GetMagnitudeStringForParam(_paramName); } } | |
public AnimParamPitchYaw(Animator animator, string param) | |
{ | |
if (animator == null) Debug.LogError("Animator is null"); | |
_anim = animator; | |
_paramName = param; | |
_hashedPitch = Animator.StringToHash(PitchString); | |
_hashedYaw = Animator.StringToHash(YawString); | |
_hashedMagnitude = Animator.StringToHash(MagnitudeString); | |
} | |
public void SetPitchYaw(float pitch, float yaw) | |
{ | |
SetPitchYaw(new Vector2(pitch, yaw)); | |
} | |
public void SetPitchYaw(Vector2 vector2) | |
{ | |
if (vector2.x > 180f || vector2.y > 180f || vector2.x < -180f || vector2.y < -180f) | |
{ | |
Debug.LogWarning("Given angle is outside of range -180..+180. Use '.DeltaAngles' to correct the range"); | |
} | |
_vectorValue = vector2; | |
_anim.SetFloat(_hashedPitch, vector2.x); | |
_anim.SetFloat(_hashedYaw, vector2.y); | |
_anim.SetFloat(_hashedMagnitude, vector2.magnitude); | |
} | |
public override string ToString() | |
{ | |
return _paramName; | |
} | |
public void SetPitchYaw(Quaternion rot) | |
{ | |
//Vector3 deltaEulers = rot.eulerAngles.DeltaAngles(); | |
Vector3 euler = rot.eulerAngles; | |
Vector3 deltaEulers = new Vector3(Mathf.DeltaAngle(0.0f, euler.x), Mathf.DeltaAngle(0.0f, euler.y), Mathf.DeltaAngle(0.0f, euler.z)); | |
SetPitchYaw(deltaEulers.x, deltaEulers.y); | |
} | |
} | |
public static class AnimatorExtentions { | |
public static AnimParam AnimParam(this Animator anim, string ParamName) | |
{ | |
return new AnimParam(anim, ParamName); | |
} | |
public static AnimParam3 AnimParam3(this Animator anim, string ParamName) | |
{ | |
return new AnimParam3(anim, ParamName); | |
} | |
public static AnimParamPitchYaw AnimParamPitchYaw(this Animator anim, string ParamName) | |
{ | |
return new AnimParamPitchYaw(anim, ParamName); | |
} | |
public static int GetLayerNumberForName(this Animator anim, string name) | |
{ | |
int numLayers = anim.layerCount; | |
for(int i = 0 ; i < numLayers; i++ ) | |
{ | |
if (anim.GetLayerName(i) == name) return i; | |
} | |
Debug.Log("Layer name " + name + " not found in animator " + anim.name); | |
return -1; | |
} | |
} |
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 UnityEngine; | |
[RequireComponent(typeof(Animator))] | |
public class AnimatorFeed : MonoBehaviour | |
{ | |
private Animator _anim;//we need an animator to register our parameters to at runtime. | |
//Make some parameters to feed the animator with | |
//NB you need to set up the Parameters that these produce on your AnimatorController, manually. | |
private AnimParam _speed; //just magnitude | |
private AnimParam3 _velocity;//velocity relative to this transform | |
private AnimParamPitchYaw _headAngles;//head angles relative to this transform | |
private Vector3 _lastPosition;//store the last position we were at so that we can calculate velocity. | |
private Transform _transform;//good practice to cache off reference to transform (optimisation) | |
public Transform HeadTransform;//point at a camera or head that the player is controlling or whatever! | |
void Awake() | |
{ | |
_anim = GetComponent<Animator>(); | |
//declare our parameters | |
_speed = _anim.AnimParam("Speed");//create a parameter, and auto store its hash for better performance. | |
_velocity = _anim.AnimParam3("Velocity");//create a triad of parameters called "VelocityX", "VelocityY", "VelocityZ" | |
_headAngles = _anim.AnimParamPitchYaw("HeadAngles");//create three parameters called "HeadAnglesPitch", "HeadAnglesYaw" and also "HeadAnglesMagnitude" | |
_transform = transform; | |
_lastPosition = _transform.position; | |
} | |
void Update() | |
{ | |
Vector3 deltaPosition = _transform.position - _lastPosition; | |
_lastPosition = _transform.position;//lest we forget | |
Vector3 vel = deltaPosition / Time.deltaTime; | |
//put into local space | |
vel = _transform.InverseTransformDirection(vel); | |
_speed.FloatValue = vel.magnitude;//This will update animator parameter "Speed" | |
_velocity.Vector3Value = vel;//This will update animator parameters "VelocityX", "VelocityY", "VelocityZ" all at once | |
Quaternion relativeRotation = Quaternion.Inverse(_transform.rotation) * HeadTransform.rotation; | |
_headAngles.SetPitchYaw(relativeRotation);//you can also use eulers, but everyone thinks you are more of a cleverer nerd if you use quaternions | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment