Search Unity

How do I trigger animations through script?

Discussion in '2D' started by Sencored, May 15, 2017.

  1. Sencored

    Sencored

    Joined:
    May 15, 2017
    Posts:
    11
    My terminology in the title may be a bit off, but let's see if I can't get my point across here. What I am trying to do is make a coin that plays one animation when the game starts(I have no problem with this part) and when I collect that coin, it plays a little animation of a few little twinkly stars fading out. I have both animations made and, like I said, have no problem playing the default one. My problem lies in getting the animation to play when I collect the coin. I am assuming playing an animation requires it to be legacy, but it does not play the animation and gives me these two errors; "
    Animator.GotoState: State could not be found
    UnityEngine.Animator:play(String)
    Player:OnTriggerEnter2D(Collider2D) (at Assets/Scripts/Player.cs:146)
    " and "
    Invalid Layer Index '-1'
    UnityEngine.Animator:play(String)
    Player:OnTriggerEnter2D(Collider2D) (at Assets/Scripts/Player.cs:146)
    " Here is a chunk of my code. Do note that I have two different kinds of coins that add different amounts of money to the value (gm.coins).

    void OnTriggerEnter2D(Collider2D col)
    {

    if(col.CompareTag("BigCoin"))
    {
    gameObject.GetComponent<Animator>().Play("Coin_Collect_Anim");
    Destroy(col.gameObject);
    gm.coins += 5;
    }

    if (col.CompareTag("Coin"))
    {
    gameObject.GetComponent<Animator>().Play("Coin_Collect_Anim");
    Destroy(col.gameObject);
    gm.coins += 1;
    }

    }
     
  2. Sencored

    Sencored

    Joined:
    May 15, 2017
    Posts:
    11
    Side note, those little tongue out emotes are .P, I have no idea how to deformat those.
     
    levilindsey likes this.
  3. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    Use code tags for auto-pretty code.

    The console is saying there are no states in your animator named "Coin_Collect_Anim". Are you sure this is the name of the Animator state, and not the animation clip? Which object is supposed to play the animation? The Player? Or the Coin? In the script provided above, the Player is trying to play Coin_Collect_Anim rather than the Coin, and I can't tell whether that's intentional.
     
  4. Sencored

    Sencored

    Joined:
    May 15, 2017
    Posts:
    11
    Oh, that is not intentional. I copied from another one of my codes that doesn't work, not thinking about that. So pretend the coin was supposed to be played by the player, why isn't it working? You said something about an animation state and not the clip? I just figured out that I needed to write a separate code for the coins to play their animation, but every script that calls for an animation to be played is not working (it never was), so I came up with an idea. I could set a variable for the animation that is to be played so I could drag it into a spot on the script behavior in the editor to avoid misnaming things and messing things up. The only problem is I do not know how to do this. lol I have no idea how to ask for an animation or how to implement the variable into the
    Code (csharp):
    1. gameObject.GetComponent<Animator>().Play(???possibly put variable name here???);
    line instead of the string name of the animation.

    I was thinking of something like this...

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Coin : MonoBehaviour {
    7.     private Animator anim;
    8.     private gameMaster gm;
    9.  
    10.     public animationPlayed;
    11.  
    12.         void Update()
    13.         {
    14.         anim.Set???(????);
    15.         }
    16.  
    17.     void OnTriggerEnter2D(Collider2D col)
    18.     {
    19.  
    20.         if (col.CompareTag("BigCoin"))
    21.         {
    22.             gameObject.GetComponent<Animator>().Play("Coin_Collect_Anim");
    23.             Destroy(col.gameObject);
    24.             gm.coins += 5;
    25.         }
    26.  
    27.         if (col.CompareTag("Coin"))
    28.         {
    29.             gameObject.GetComponent<Animator>().Play("Coin_Collect_Anim");
    30.             Destroy(col.gameObject);
    31.             gm.coins += 1;
    32.         }
    33.  
    34.     }
    35.  
    36. }
    37.  
    this is probably wayyyyy far off from what I am supposed to do, but I am at a loss and am trying to push my very limited knowledge of code to the threshold. Keep in mind, I have very little knowledge of C#, so if my code looks completely outlandish, you know why. I am not stupid, just ignorant. lol
     
    Last edited: May 16, 2017
  5. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    Can we have a screen shot of your Animator controller? I don't make any use of Animator.Play(), so I honestly am not really sure how it's supposed to work. The documentation is lacking, but I do know that string names of animator states are sometimes expected to be prefixed with the layer name, which is "BaseLayer" by default (or "Base" in older versions). This should be included inside of the string that defines the layer name.

    Here's an example:

    gameObject.GetComponent<Animator>().Play("BaseLayer.Coin_Collect_Anim");

    Check your layer name in your Animator to confirm its name. I have no idea if this will work or not, so you'll have to try it out.

    If this doesn't work, it might be better to set up your Animator with simple transitions that trigger with parameters, and use that method instead, which we can help you with.
     
  6. Sencored

    Sencored

    Joined:
    May 15, 2017
    Posts:
    11
    Do you want a screen shot of the coin animator controller or the player? There is nothing to the coin anim controller. It is just a starting state. No animations. Also, I tried that adding the BaseLayer prefix and it did nothing.
     
  7. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    If there are no states in the Animator, then nothing will happen for sure. Animator.Play() asks for an animator state, not an animation clip, which is the distinction I was trying to point out before. The Animator uses states to play animations and transitions to move between them.

    Have you looked at the Animator tutorials (those listed under Controlling Animation)? I feel that you're having some fundamental misunderstandings about how Mecanim works and should definitely check them out. Just in case you weren't already, make sure you understand the difference between the Animation and Animator components, because they're very different.

    What's in the player controller, then, since the coin one is empty?
     
  8. Sencored

    Sencored

    Joined:
    May 15, 2017
    Posts:
    11
    Oh, I am new so fundamental misunderstandings are unavoidable. haha Yeah, sorry for not picking up on what you were trying to say before, but the thing is I am using legacy, and legacy animations are not supposed to make an appearance in your animator controllers. I used a video by a young man by the user GucioDevs on YouTube to make this animation and dispite following his instructions to a T, it does not work. Here is the link:
     
  9. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    If you're using the legacy Animation component, then use Animation.Play(), not Animator.Play(). Be wary of mixing these classes up.

    Also remember that you don't need an Animator on an object that only uses legacy animation.


    A couple things to keep in mind:

    -The Animation component will eventually be depreciated, and is included in current versions of Unity for compatibility with older projects. I suggest moving toward using the Animator component for all animation.

    -I don't see the point in mixing Animation/Animator components. Some still will use Animation for very simple things, but if there's already an Animator controller set up with states and transitions and everything, why convolute things? The video suggests that its necessary in order to change the color of the character without interrupting the existing animation states, but this can be done in Mecanim using layers or multiple controllers.

    -As if the Animation/Animator naming wasn't confusing enough, remember that the Animation component and the Animation view are two different things as well.
     
  10. Sencored

    Sencored

    Joined:
    May 15, 2017
    Posts:
    11
    I tried changing it to Animation (instead of Animator) before and remember it not working. I can try again though. Also, why use layers and multiple controllers when you can just write a few lines of script? That seems unnecessary.
     
  11. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    Because the Animation component is legacy, and mixing them will almost certainly lead to more than just a few lines when it comes to making sure they don't conflict with each other. Besides, using up-to-date methods isn't any more complex if you're doing a non-complex thing, but it will allow you more flexibility if you want to expand a feature later on, whereas the Animation component is extremely limited without much, much more scripting.

    Just some things to think about. For now, Animation is still around, so use it as you see fit, but these are my genuine recommendations.
     
  12. FullHeartGames

    FullHeartGames

    Joined:
    Jul 21, 2015
    Posts:
    18
    I posted a tutorial a lot of it having to do with animation and shows the complete process of adding parameters to animations and setting up the Animator etc. My comment was deleted, let me know if anyone is interested can ry and repost.
     
  13. FullHeartGames

    FullHeartGames

    Joined:
    Jul 21, 2015
    Posts:
    18
  14. Carterryan1990

    Carterryan1990

    Joined:
    Dec 29, 2016
    Posts:
    79
    int jump = Animator.StringToHash("Jump");--//Make sure Trigger parameter in animator controller is wrote the same way that you string it//

    void Update()
    {
    if (Input.GetKeyDown(KeyCode.Space))
    {
    ani.SetTrigger(jump);
    }
     
    Last edited: Jan 27, 2018