• Unity
  • Question about interrupting/stopping animation

Related Discussions
...

SOLVED: While I don't entirely understand why it worked, it helped that hit animations are not set on loop... =)

Heya, this is most likely due my inability as a coder but I've got a question...

The setup
Right now I've got Unity project with 4 direction movement using Spine animations. I've got a game object for each skeleton (front, back, side) and a animation controller that changes between walk, idle and attack animations and based on what direction you are facing it disables the other game objects (= if you turn right, the objects with front and back animations get disabled).

Problem
If I hit downward and in middle of attack animation turn left (game object that contains downward hit gets disabled) the hit animation is "stored" and even after 3-4 minutes if I then return back facing downwards the hit animation resumes where it left off before disabling the game object that contains it.

Here's part of my animation controller

public class c_playeranimationcontroller : MonoBehaviour 
{

   public GameObject animations_front;
   public GameObject animations_back;
   public GameObject animations_side;
   public GameObject hitAndUseArea;
   GameObject player;
   c_playercontroller Player_c;
   SkeletonAnimation skel_front;
   SkeletonAnimation skel_back;
   SkeletonAnimation skel_side;
   string currentAnimation = "";


   //Set the connections to other scripts etc.
   void Start()
   {
      skel_front =  animations_front.GetComponent<SkeletonAnimation>();
      skel_back =  animations_back.GetComponent<SkeletonAnimation>();
      skel_side =  animations_side.GetComponent<SkeletonAnimation>();
      player = GameObject.FindGameObjectWithTag("Player"); 
      Player_c = player.GetComponent<c_playercontroller>();
   }
      
   //Listen to animation changes constantly
   void Update()
   {
      animateWalk();
   }
      
   //ATTACK ANIMATIONS 
   public void animateAttack()
   {
      if(Player_c.direction ==  c_playercontroller.Direction.Up) 
      {    
         PlayAnimation(skel_back, 0, "hit_back", true);
      }
      else if(Player_c.direction ==  c_playercontroller.Direction.Down) 
      {    
         PlayAnimation(skel_front, 0, "hit_front", true);
      }
      else if(Player_c.direction ==  c_playercontroller.Direction.Right)
      {   
         PlayAnimation(skel_side, 0, "hit_side", true); 
      }
      else if(Player_c.direction ==  c_playercontroller.Direction.Left) 
      {  
         PlayAnimation(skel_side, 0, "hit_side", true);
      }

   }

   //WALK AND IDLE ANIMATIONS
   void animateWalk()
   {
      if(!Player_c.isHitting){
         if(Player_c.input_y != 0 || Player_c.input_x != 0)
         {   
            if(Mathf.Abs(Player_c.input_y) > Mathf.Abs(Player_c.input_x))
            {
               if (Player_c.input_y > 0) 
               {   
                  animations_front.SetActive(false);   animations_side.SetActive(false); animations_back.SetActive(true); 
                  PlayAnimation(skel_back, 0, "walk_back", true);
                  Player_c.direction = c_playercontroller.Direction.Up;
                  hitAndUseArea.transform.position = transform.position + new Vector3(0,-7,0);
               }
               else if (Player_c.input_y < 0) 
               {
                  animations_front.SetActive(true); animations_side.SetActive(false); animations_back.SetActive(false); 
                  PlayAnimation(skel_front, 0, "walk_front", true);
                  Player_c.direction = c_playercontroller.Direction.Down;
                  hitAndUseArea.transform.position = transform.position + new Vector3(0,-42,0);
               }
            }
            else
            {
               if (Player_c.input_x > 0) 
               {
                  animations_front.SetActive(false); animations_side.SetActive(true); animations_back.SetActive(false); animations_side.transform.localRotation = Quaternion.Euler(0,0,0); 
                  PlayAnimation(skel_side, 0, "walk_side", true);
                  Player_c.direction = c_playercontroller.Direction.Right;   
                  hitAndUseArea.transform.position = transform.position + new Vector3(28,-20,0);
               }
               else if (Player_c.input_x < 0) 
               { 
                  animations_front.SetActive(false); animations_side.SetActive(true); animations_back.SetActive(false); animations_side.transform.localRotation = Quaternion.Euler(0,180,0); 
                  PlayAnimation(skel_side, 0, "walk_side", true);
                  Player_c.direction = c_playercontroller.Direction.Left;
                  hitAndUseArea.transform.position = transform.position + new Vector3(-28,-20,0);
               }
            }

     }
     else 
     {
        if(Player_c.direction == c_playercontroller.Direction.Up)             {       PlayAnimation(skel_back, 0, "stand_back", true);}
        else if(Player_c.direction == c_playercontroller.Direction.Down)    {       PlayAnimation(skel_front, 0, "stand_front", true);}
        else if(Player_c.direction == c_playercontroller.Direction.Right)    {      PlayAnimation(skel_side, 0, "stand_side", true);}
        else if(Player_c.direction == c_playercontroller.Direction.Left)    {        PlayAnimation(skel_side, 0, "stand_side", true);}
     }
  }

   }
      
   //SPINE FUNCTION FOR STARTING ANIMATION
   void PlayAnimation(SkeletonAnimation anim, int layer, string name, bool trueornot)
   {
      if(name == currentAnimation)
         return;

  anim.state.SetAnimation(layer, name, trueornot);
  currentAnimation = name;
   }

Is there a call for reset-animation. Any other ideas?

I think you need to call
skel_front.state.ClearTracks(); (to remove the animation)
and
skel_front.skeleton.SetToSetupPose(); (to reset the skeleton)

at the correct points in time. Probably before playing a new animation or enabling/disabling the SkeletonAnimation components.