I’m fairly sure you have to use the Animation name for Legacy. A handy thing you can do is get all Animation Names though and look for something that is “Like” that name.
protected string GetAnimationNameFromList(string animationName)
{
foreach(AnimationState s in characterAnimation)
{
if(s.name.ToLower().Contains(animationName.ToLower()))
{
return s.name.ToString();
}
}
return "";
}
So if you had CharacterOne_Jump and another Character with CharacterTwo_Jump and you called GetAnimationNameFromList(“jump”) it would return either for you.
Looking at your code I noticed that your simply using the “Play()”. I would probably suggest you switch over to CrossFade so it smoothly attempts to transition from your jump into a run again.
The way we created our “AnimationController” was generic enough to work with all characters.
Example of one of the methods:
// This plays the Animation forward.
public float PlayAnimation(string animationName, float speed, string callBack = "", GameObject reciever = null, bool npc = false)
{
// Play the animation
characterAnimation[animationName].normalizedTime = 0f;
characterAnimation[animationName].speed = speed;
characterAnimation.CrossFade(animationName, 0.1f);
// Block the idle and run animation
if ((reciever != null) !string.IsNullOrEmpty(callBack))
{ // If the caller wants a message when the animation is finished
StartCoroutine(AnimationCallBackTimer(characterAnimation[animationName].length/speed, callBack, reciever));
}
else
{
StartCoroutine(AnimationTimer(characterAnimation[animationName].length/speed));
}
return characterAnimation[animationName].length;
}
//This will play the animation backwards.
public float PlayAnimationBackwards(string animationName, float speed, string callBack = "", GameObject reciever = null, bool npc = false)
{
characterAnimation[animationName].normalizedTime = 1f;
characterAnimation[animationName].speed = speed;
characterAnimation[animationName].time = characterAnimation[animationName].length;
characterAnimation.CrossFade(animationName, 0.1f);
if ((reciever != null) !string.IsNullOrEmpty(callBack))
{
StartCoroutine(AnimationCallBackTimer(characterAnimation[animationName].length/Mathf.Abs(speed), callBack, reciever));
}
else
{
StartCoroutine(AnimationTimer(characterAnimation[animationName].length/Mathf.Abs(speed)));
}
return characterAnimation[animationName].length;
}
Instead of handling your Running and Idling… Just base that off of movement.
Example:
if(IsMoving())
{
currentAnimationSpeed = runAnimationSpeed;
PlayAnimation(RunAnimation);
idleAnimPlayed = false;
}
else
{
//Not moving so were idle
currentAnimationSpeed = idleAnimationSpeed;
if (RandomIdleAnimStart !idleAnimPlayed)
{ // If we shall start at a random point of the animation (only for the firt time)
characterAnimation[IdleAnimation].normalizedTime = UnityEngine.Random.Range(0.0f, 0.8f);
}
if (characterAnimation[IdleAnimation].normalizedTime >= 1.0f)
{ // When the Idle animation is finished we call the event
if (IdleAnimationFinished != null)
{
IdleAnimationFinished();
characterAnimation[IdleAnimation].normalizedTime = 0.0f;
}
}
PlayAnimation(IdleAnimation);
idleAnimPlayed = true;
}
Simple IsMoving() checker for you
private bool IsMoving()
{
bool isMoving = false;
//Calculate the movement velocity of the character.
difference = myTrans.position - lastPos;
lastPos = myTrans.position;
playerVel = difference / Time.deltaTime;
if(playerVel.sqrMagnitude > movementThreashhold)
{
isMoving = true;
}
return isMoving;
}
Obviously don’t take my examples and throw them in Unity and think they will work with your Solution but you can get the jest of what is going on.
** And I’m sure your not wanting to jump and run or idle at the same time. So you can do a check before those checks to see if your in any other State. We use a boolean. So if your not in a “Movement State” => Casting an Ability. It won’t attempt to run or idle until its done.
if(conflictingAnimation)
{
return;
}