Skip to content

Instantly share code, notes, and snippets.

@builder-main
Forked from pazzaar/AnimatorExtensions
Last active January 17, 2023 05:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save builder-main/40b429fce73b60301c73977614389948 to your computer and use it in GitHub Desktop.
Save builder-main/40b429fce73b60301c73977614389948 to your computer and use it in GitHub Desktop.
Animator rebind function that also maintains some state
public static class AnimatorExtensions
{
public static AnimatorParametersState SaveState(this Animator anim)
{
List<AnimatorStateInfo> animStates = new List<AnimatorStateInfo>();
for (int i = 0; i < anim.layerCount; i++)
{
animStates.Add(anim.GetCurrentAnimatorStateInfo(i));
}
List<AnimatorParameterInfo<bool>> animBoolParams = new List<AnimatorParameterInfo<bool>>();
List<AnimatorParameterInfo<float>> animFloatParams = new List<AnimatorParameterInfo<float>>();
List<AnimatorParameterInfo<int>> animIntParams = new List<AnimatorParameterInfo<int>>();
foreach (var param in anim.parameters)
{
switch (param.type)
{
case (AnimatorControllerParameterType.Bool):
var boolParam = new AnimatorParameterInfo<bool>()
{
name = param.name,
value = anim.GetBool(param.name)
};
animBoolParams.Add(boolParam);
break;
case (AnimatorControllerParameterType.Float):
var floatParam = new AnimatorParameterInfo<float>()
{
name = param.name,
value = anim.GetFloat(param.name)
};
animFloatParams.Add(floatParam);
break;
case (AnimatorControllerParameterType.Int):
var intParam = new AnimatorParameterInfo<int>()
{
name = param.name,
value = anim.GetInteger(param.name)
};
animIntParams.Add(intParam);
break;
}
}
var saveState = new AnimatorParametersState(animBoolParams, animFloatParams, animIntParams, animStates);
return saveState;
}
public class AnimatorParametersState
{
public List<AnimatorParameterInfo<bool>> animBoolParams { get; }
public List<AnimatorParameterInfo<float>> animFloatParams { get; }
public List<AnimatorParameterInfo<int>> animIntParams { get; }
public List<AnimatorStateInfo> animStates { get; }
public AnimatorParametersState(List<AnimatorParameterInfo<bool>> animBoolParams, List<AnimatorParameterInfo<float>> animFloatParams, List<AnimatorParameterInfo<int>> animIntParams, List<AnimatorStateInfo> animStates)
{
this.animBoolParams = animBoolParams;
this.animFloatParams = animFloatParams;
this.animIntParams = animIntParams;
this.animStates = animStates;
}
}
public static void RestoreState(this Animator anim, AnimatorParametersState save)
{
var animStates = save.animStates;
var animBoolParams = save.animBoolParams;
var animFloatParams = save.animFloatParams;
var animIntParams = save.animIntParams;
anim.Rebind();
for (int i = 0; i < anim.layerCount; i++)
{
anim.Play(animStates[i].fullPathHash, i, animStates[i].normalizedTime);
//I've found .Play works better for me, but I think a CrossFade could work here too...
//anim.CrossFade(animStates[i].fullPathHash, .2f, i, animStates[i].normalizedTime);
}
foreach (var param in animBoolParams)
{
anim.SetBool(param.name, param.value);
}
foreach (var param in animFloatParams)
{
anim.SetFloat(param.name, param.value);
}
foreach (var param in animIntParams)
{
anim.SetInteger(param.name, param.value);
}
}
public struct AnimatorParameterInfo<T>
{
public string name;
public T value;
}
}
@builder-main
Copy link
Author

A fork that allow to save and restore animator parameters at a later time or on another one, such as a new instance. Not thoroughfly tested but seems to work for my usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment