Sprite animation only playing first frame
I am currently having the problem that, although my animator controller appears to be set up correctly, my animations are not playing. I am currently coding a 2D walking sprite that changes animation clips based on the direction in which he is walking, and my animator indeed switches correctly between the different directional animation clips – however, it only plays the first frame, and immediately stops there. In my animator window, the correct clip that should be playing is selected, but the bar that shows the progress is not moving.
This is an issue I've never had with Unity animations, and I'm honestly stumped on this. Has anybody had this problem before, or does anybody have an idea of how to fix it?
Thank you!
Answer by OctoMan · Nov 06, 2015 at 05:54 PM
There are several things you need to check.
Does your animation in the animation window works correct?
Is the speed variable of the animation set to 1?
Did all worked before you started coding?
Answer by thegirlnamedcrow · Dec 17, 2015 at 11:54 PM
@OctoMan Yes, to all of these. Sorry this took so long for me to answer this - I'm going to add some information that might help.
I'm using a spritesheet with a character that moves in the NW/SW/NE/SE directions, and I'm trying to route everything through any state in order to make smooth transitions. Let me post my code: this animation is called during the same frame that the destination is set.
using UnityEngine;
using System.Collections;
public class BehaviorSeek : MonoBehaviour
{
public float Step;
public float StoppingRadius;
private Animator anim;
Vector3 destination;
void Start()
{
anim = GetComponent<Animator>();
anim.SetBool("SW", true);
anim.SetBool("Idle", true);
destination = new Vector3 (0f, 0f, 0f);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
destination = Camera.main.ScreenToWorldPoint(Input.mousePosition);
destination = new Vector3(destination.x, destination.y, destination.y);
}
if (CheckIfInRange(destination))
{
UpdateAnim(destination, false);
}
else if (!CheckIfInRange(destination))
{
MoveTo(destination);
}
}
bool CheckIfInRange(Vector3 dest)
{
if (GetHypotenuse(transform.position, dest) <= StoppingRadius)
{
return true;
}
else { return false; }
}
float GetHypotenuse(Vector3 first, Vector3 second)
{
float diff = Vector3.Distance(first, second);
return diff;
}
public void MoveTo(Vector3 dest)
{
UpdateAnim(dest, true);
Vector3 newPos = Vector3.Lerp(transform.position, dest, Step * Time.deltaTime);
transform.position = newPos;
}
void UpdateAnim(Vector3 dest, bool isMoving)
{
if (!isMoving)
{
anim.SetBool("Idle", true);
anim.SetBool("Moving", false);
}
else if (isMoving)
{
Vector3 pos = transform.position;
if (dest.x > pos.x) //east
{
if (dest.y > pos.y) // north
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", false);
anim.SetBool("SE", false);
anim.SetBool("SW", false);
anim.SetBool("NE", true);
}
else if (dest.y == pos.y) // south
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", false);
anim.SetBool("SE", true);
anim.SetBool("SW", false);
anim.SetBool("NE", false);
}
else if (dest.y < pos.y) // south
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", false);
anim.SetBool("SE", true);
anim.SetBool("SW", false);
anim.SetBool("NE", false);
}
}
else if (dest.x == pos.x) // west
{
if (dest.y > pos.y) // north
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", true);
anim.SetBool("SE", false);
anim.SetBool("SW", false);
anim.SetBool("NE", false);
}
else if (dest.y == pos.y) // south
{
anim.SetBool("Moving", false);
anim.SetBool("Idle", true);
}
else if (dest.y < pos.y) //south
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", false);
anim.SetBool("SE", false);
anim.SetBool("SW", true);
anim.SetBool("NE", false);
}
}
else if (dest.x < pos.x) // west
{
if (dest.y > pos.y) //north
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", true);
anim.SetBool("SE", false);
anim.SetBool("SW", false);
anim.SetBool("NE", false);
}
else if (dest.y == pos.y) //south
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", false);
anim.SetBool("SE", false);
anim.SetBool("SW", true);
anim.SetBool("NE", false);
}
else if (dest.y < pos.y) //south
{
anim.SetBool("Idle", false);
anim.SetBool("Moving", true);
anim.SetBool("NW", false);
anim.SetBool("SE", false);
anim.SetBool("SW", true);
anim.SetBool("NE", false);
}
}
}
}
}
Here's the basics of my animator component, attached!
Please let me know if there's anything else I can show you that might help.
Answer by jste6370 · Feb 12, 2021 at 01:55 AM
I set up my idle animation in the animator so that "Any State" could could transition to idle. The problem with this is that: "Any State" includes the animation itself and there is an infinite loop causing only the first frame to show and is why the animation doesn't play.
I fixed this by: Click the transition link in the animator > In the inspector, expand settings > untick "Can Transition To"
Now my idle animation plays! I know this is almost 6 years old but it comes up first on google for me. Hope it helps lol
Your answer
Follow this Question
Related Questions
Bone length found in file is differn't then source 0 Answers
how do I create a custom sprite class 0 Answers
Animation changes when marked as legacy 0 Answers