Search Unity

How to reset an animation from Animator?

Discussion in '2D' started by eanjo7, Jun 30, 2014.

  1. eanjo7

    eanjo7

    Joined:
    Jun 1, 2014
    Posts:
    42
    Hi i have a 2d sprite animation, and automatically plays at start. can I stop it from playing at start?

    And If my 2d animation ends, how can I reset it from playing it from the beginning of the animation?

    cause calling animator.Play("animatioNameSample");

    is not resetting it from going back to the beginning of animation.

    pls help!
     
  2. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297

    If you dont want it to play at start, create an idle animation with only 1 sprite. Then transition between the animation and no animation in script. Its simple. :)
     
    grfxguru likes this.
  3. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Hey I'm having a similar problem like eanjo7 does except more complex. You see, my animation changes from Idle to Boost when I grab a certain gameobject tagged with Item2, but the problem is that the animation doesn't change back to Idle. It stays the same. How can I change it back after about 5 seconds? If you know please share. ;)
    Script:

    Code (CSharp):
    1. GameObject Character;
    2. Animator anim;
    3. void Awake()
    4.     {
    5.      
    6.         anim = GameObject.FindGameObjectWithTag("Player").GetComponent<Animator>();
    7.      
    8.     }
    9. void  OnTriggerEnter2D ( Collider2D Other  ){
    10.         anim.SetBool ("Boost", true);
    11.         if(Other.collider.tag == "Player"){
    12.          
    13.             anim.SetBool ("Boost", false);
    14.         }
    15.     }
    16. }
    By the way I tried adding a coroutine, but it's not working out for me so far.
     
    Last edited: Jul 1, 2014
  4. eanjo7

    eanjo7

    Joined:
    Jun 1, 2014
    Posts:
    42
    what Im doing since I do not know how to reset it in the right way is.

    animator.setActive( false );
    animtor.setActive( true );

    this will reset it, but I want to know lik .stop() or something.
     
  5. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Well I'm not good at resetting either, hence why I asked Rutenis to share some knowledge with me if he had any. I, earlier on, used public float timer to reset my animation, though it is NOT very efficient. It wasn't precise on the timing of when the animation resets and sometimes it didn't even work at all. I'm currently trying to fix this. So if you want to use it then go ahead but expect problems.
     
  6. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297

    Did you checked your transitions, set boost to be false when you want it to transition back to idle, because It should work. If you want to set your bool to true after 5 seconds:


    1. GameObject Character;
    2. Animator anim;
    3. void Awake()
    4. {
    5. anim = GameObject.FindGameObjectWithTag("Player").GetComponent<Animator>();
    6. }
    7. void OnTriggerEnter2D ( Collider2D Other ){

    8. StartCoroutine(WaitForAnimationToPlay());

    9. if(Other.collider.tag == "Player"){
    10. anim.SetBool ("Boost", false);
    11. }
    12. }
    13. IEnumerator WaitForAnimationToPlay()
      {
    14. yield return new WaitForSeconds(5);
    15. anim.SetBool("Boost", true);
    16. }
    17. }
     
  7. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297

    Try anim.Pause(); OR anim.Stop; OR anim.Stop("Animation");
     
  8. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Should I have my Boost state in the animator be connected to my Idle state or Any State? Currently Any State has a transition to Boost, while Boost has a transition to Idle, and Idle has a transition to Boost. So Idle and Boost go back and forward, while Any State only goes to Boost. Boost doesn't have a transition to Any State.
     
  9. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Set the transitions to be from idle to boost and from boost to idle, so you would have 2 transitions. From animation to idle set the boost to be false, and from idle to animation set the boost to be true.In this case, dont use transitions from any state.
     
  10. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Okay then thanks, and one more question I need to ask you. Do I need the "if(Other.collider.tag == "Player"){" to be a collider or a gameobject? So something like this: "if(Other.gameObject.tag == "Player"){". I ask this because my game gets an error when I grab the power up, saying:
    Code (CSharp):
    1. MissingComponentException: There is no 'Collider' attached to the "Player" game object, but a script is trying to access it.
    2. You probably need to add a Collider to the game object "Player". Or your script needs to check if the component is attached before using it.
    3. AnotherAnim.OnTriggerEnter2D (UnityEngine.Collider2D Other) (at Assets/Scripts/Animation/AnotherAnim.cs:50)
    When I change it the gameObject, it does not give me any errors. It doesn't work though. The coroutine does nothing when I use gameObject. By the way I have two box collider 2D's attached to the Player and of course a Rigidbody2D, so how can there be no collider?
     
    Rutenis likes this.
  11. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297

    I always use "Other.gameObject.tag == "Tag". And dont forget you have to use 2d on collisionEnter2d:) Because its says that its looking for Collider, not for Collider2D, that means your not using void OnCollisionEnter2D. :) This is the right way to do:

    Code (csharp):
    1. if(Other.gameObject.tag == "Tag")
    2. {
    3.  
    4. }
    5.  
    6.  
    7. Void OnCollisionEnter2D(Collision2D Other)
    8. {
    9.  
    10. }
     
  12. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Alright then. I made a new script and now it no longer gives me that error, but now it doesn't change my animation from Idle to Boost anymore when I grab the power up. Maybe I made a mistake in the script? Here's my new script:

    Code (CSharp):
    1. GameObject Character;
    2.  
    3. Animator anim;
    4.  
    5. void Awake()
    6.     {
    7.        
    8.         anim = GameObject.FindGameObjectWithTag("Player").GetComponent<Animator>();
    9.  
    10.        
    11.     }
    12.  
    13. void  OnCollisionEnter2D ( Collision2D Other  ){
    14.  
    15.         StartCoroutine(WaitForAnimationToPlay());
    16.  
    17.         if(Other.gameObject.tag == "Player"){
    18.             anim.SetBool ("Boost", false);
    19.         }
    20.     }
    21.     IEnumerator WaitForAnimationToPlay()
    22.     {
    23.         yield return new WaitForSeconds(5);
    24.         anim.SetBool("Boost", true);
    25.     }
    26. }
    27.  
     
  13. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    StartCoroutine when you hit the player, if that doesnt workt, tell me;)
    1. void OnCollisionEnter2D ( Collision2D Other ){


    2. if(Other.gameObject.tag == "Player")
    3. {
    4. anim.SetBool ("Boost", false);
    5. StartCoroutine(WaitForAnimationToPlay());
    • }
     
  14. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    I'm afraid that it doesn't work. I checked the animator to see if it even plays my animation, and it doesn't. Debugging doesn't even work either. Are you sure we should transition from Idle to Boost and Boost to Idle? I did that before and it didn't work, then some other guy recommended I use Any State. So I'm confused on which one is better.
     
  15. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Well, it depends. For example, when i start the game, my default animation is set to be idle. Then whenever i press any button, my animation transitions to another animation, when i stopped pressing any button it transitions back to my idle animation. Im not sure if thats the case for you. Can you explane little more what youre trying to do ?:)
     
  16. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    What I'm trying to do is similar, but not quite like that. You see, I want my animation to change from my default Idle state to another animation when I grab a certain power up, and then return back to Idle after 5 seconds. So it changes on collision, not by pressing a button. I had it before but sometimes it didn't work, and it sometimes changed 30 seconds after I grabbed the power up and changed my animation. So it never worked correctly. I used timer = 0 and timer = 5.
     
  17. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    maybe you should use trigger. Are you destroying the power up emediatly after the player touches it? If so i would suggest you to use Triggers. Take your PowerUp in the Inspector set Is Trigger to be checked.

    void OnTriggerEnter2D(Collider2D coll)
    {
    if(coll.gameObject.tag == "Tag")
    {
    anim.SetBool ("Boost", false);
    }
    }

    Can you tell me what other scripts are attached to your Player, that youre moving, because i could see whats going on there. It would help me.:)
     
  18. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Here's how it's supposed to work. I collect 5 normal power ups, and a special one spawns. That special one is the one that's supposed to change my animation. After I grab that one it disappears immediately, but will come back after I collect 5 more normal power ups. Currently that doesn't work and the special power up just spawns right when I play the game. I'll try using the trigger again.

    The other scripts that are attached to my Player are: Player Controller script, Pause Menu script, a Collider script for the special power up to let it's speed up effect take place, and a power up spawn script that spawns the power ups(though I have it attached to both normal and special powerup, so I don't need it on the Player).
     
  19. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297

    Now i would suggest you to use Player Controller script for animations. It should work. :/


    Code (csharp):
    1. Animator anim;
    2.  
    3. void Start()
    4. {
    5. anim = GetComponent<Animator>();
    6. }
    7.  
    8.  
    9. void OnTriggerEnter2D(Collider2D coll)
    10. {
    11. if(coll.gameObject.tag == "Tag")
    12. {
    13. anim.SetBool("Boost", false);
    14. }
    15. }
     
  20. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    I think were getting somewhere. Here's how my Ontrigger looks like in my Player controller script:

    Code (CSharp):
    1. void OnTriggerEnter2D(Collider2D coll)
    2.     {
    3.         anim.SetBool ("Boost", true);      
    4.         if (coll.gameObject.tag == "Item2") {
    5.                         anim.SetBool ("Boost", false);
    6.                 }
    7.         }
    I put the anm.SetBool true in front of the col.gameObject because without something in front of it, it does nothing. The true changes my animation on start up, not when I grab the power up. I only did this because it wouldn't do anything when I didn't have SetBool in front of col.gameObject. Also a question for you. should I use the tag of the prefab of the special power up, or the spawn of it? The special power up spawn Gameobject inside of the Hierarchy is tagged as "Item2", while the prefab itself is tagged as "Coin". So I'm just wondering which one I should use.
     
  21. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Tag the prefab that youre touching, in this case your power up. You dont have to tag Spawn. You wont be able to collide with spawn, because it doesnt have collider on it. Only your prefab does. What problems are you having at the moment?
     
  22. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Actually my spawn does have a collider, but it's a mesh and I've heard that those don't work too well with this. The problem I'm having at the moment it getting it to actually change my animation when I grab the power up. It did it before with the very first script that I posted, except that I had that there is no collider error and the script was attached to my power up prefab, not my Player. That's mostly the problem here. Also before again, using my first script, the problem was getting it to revert back to Idle animation after 5 seconds.
     
  23. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    First of all, your idle animation is marked with ORANGE collor (IN ANIMATOR) where you transition between the animations, that way you will know what animation your player will start at the begginning of the game. Second, i dont think you should use code like this, Because it will change ANIMATOR Parameter Boost to be true every time you touch anything. So whenever you touch anything it will change the bool Boost to be true, because its not saying change the bool to be true when i hits a specific object, in this case its saying whenever i hit anything, change the bool "Boost" to be true. NOW IF THIS DOESNT WORK JUST WATCH THIS TUTORIAL, IT HELPED ME A LOT WHEN I STARTED WORKING IN 2D. :)
    1. void OnTriggerEnter2D(Collider2D coll)
    2. {
    3. anim.SetBool ("Boost", true);
    4. if (coll.gameObject.tag == "Item2") {
    5. anim.SetBool ("Boost", false);
    6. }
    7. }
     
  24. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    If none of that helped,


    Here is THE TUTORIAL video:


    Please watch it! :)
     
  25. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Yeah my Idle animation is orange, so that's good..Using the code you just provided, the animation changes on start up again. It think it's because the ground collides with my player, so it changes the animation. I just confirmed this because I disabled the ground right now, and my animation didn't change since I wasn't touching anything. So that is what that code does as you said. As for the tutorial you posted, it's a good tutorial. I watched it when I first started getting into Unity. It's the tutorial that helped me set up my animator. I guess I should watch it again to refresh my memory, since I might have missed something I didn't see back then. Thank you.
     
  26. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    If you will have any trouble just tell me.:)
     
  27. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Okay I think I got it. I just tested my script again. I made a few edits here and there and it seems to be working. The coroutine also works and the animation reverts back to Idle after 5 seconds. I'll keep testing it before I can be sure. Edit: Okay I after testing it some more it appears as though there is a pause before the animation plays, and if I collect another power up while I'm in the animation, it changes the animation back to Idle. This may or may not be a problem for me. The pause is ok I plan on having a pause before the animation changes anyways, but as for the animation changing back to Idle when I grab the same power up again, that's going to be a problem. Here's how it looks in my Player script:

    Code (CSharp):
    1. void OnTriggerEnter2D(Collider2D coll)
    2.     {
    3.         //anim.SetBool ("Boost", false);      
    4.         if (coll.gameObject.tag == "Coin") {
    5.                         anim.SetBool ("Boost", true);
    6.             StartCoroutine(WaitForAnimationToPlay());
    7.                 }
    8.         }
    9.  
    10.     IEnumerator WaitForAnimationToPlay()
    11.     {
    12.         yield return new WaitForSeconds(5);
    13.         anim.SetBool("Boost", false);
    14.     }
     
  28. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297


    What problems are you having now? It doenst transition back to idle if you collect the coin for second time?
     
  29. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    It doesn't stay as the Boost Animation when I collect the coin/power up for a second time. It just turns it back to Idle.
     
  30. Dogg

    Dogg

    Joined:
    Mar 5, 2014
    Posts:
    203
    Actually no that's not true. After testing the game even more, the reason why the animation sometimes doesn't play is because it's only connected to the Idle state. I also have a jumping animation, so when I jump and grab the power up, the animation doesn't play until I touch the ground again. This is probably the main reason why it's not working perfectly. So maybe using Any State might help, or connecting the animation to the Jump as well.
     
  31. eanjo7

    eanjo7

    Joined:
    Jun 1, 2014
    Posts:
    42
    great, but how about stopping the animation to specific, frame? I ask everything, but now one can answer it
     
  32. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Try anim.["ANIMATION"].time = 5f; to jump to a specific time in an animation. then anim.Play("ANIMATION"); and then anim.["ANIMATION"].speed = 0f. or just make an idle animation of that frame and transition to that animation, that way you even wont be needing to stop the animation.

    So the code should look like this:
    Code (csharp):
    1. void Update()
    2. {
    3. anim.["ANIMATION"].time = 5f; // OR your own time;
    4. anim.["ANIMATION].speed = 0.0f;
    5. anim.Play("ANIMATION");
    6. }
     
    Last edited: Jul 7, 2014
  33. grfxguru

    grfxguru

    Joined:
    Dec 5, 2017
    Posts:
    6
    Awesome, this helped solve a problem I was having. Thanks!
     
  34. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Looking back at these comments 4 years later made me laugh :D