Search Unity

Example of Animator.Play function

Discussion in 'Animation' started by Raybrand, May 22, 2014.

  1. Raybrand

    Raybrand

    Joined:
    Feb 6, 2012
    Posts:
    98
    Hi, Im getting started with this Humanoid animation system and I want to play an animation

    I found Animator.Play in the documentation but all it says is:

    Play(stateName: string, layer: int = -1, normalizedTime: float = float.NegativeInfinity)
    which is pretty vague to me so does anyone have any example code using this?
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Hi Raybrand

    You must be aware that mecanim and legacy animation system differ in some way.

    Take a look first at our tutorial
    http://unity3d.com/learn/tutorials/modules/beginner/animation/animator-component

    In Mecanim your animation is driven by layer of state machine, each one contain states with 1 or many animation.

    when you call Animator.Play the first parameter is the state name you want to play, layer is the layer index in which this state belong, normalizedTime is the time at which this animation clip should start when play.

    That been said, I would suggest you to use statemachine transition to manage how your animation blend togheter, this is by far more easy at the beginning unless what you want it total control of the blending.

    Sonny
     
  3. tosiabunio

    tosiabunio

    Joined:
    Jun 29, 2010
    Posts:
    115
    @Mecanim.Dev For some reason my Animator.Play calls are frequently unsuccessful. i.e. the state doesn't change.

    Code (CSharp):
    1.        
    2.         var info1 = animator.GetCurrentAnimatorStateInfo(0);
    3.         if (newState != info1.nameHash) {
    4.             animator.Play(newState, -1, 0f);
    5.             var info2 = animator.GetCurrentAnimatorStateInfo(0);
    6.             if (info1.nameHash == info2.nameHash) {
    7.                 Debug.LogWarning("State not changed");
    8.             }
    9.         }
    10.  
    This happens randomly for some of my instantiated objects but works in many cases as expected. What I'm doing wrong?

    I prefer changing states via code instead through triggers and Mecanim designed transition as this is much simpler for me and my animator.
     
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The animator must be ticked by the game engine before it start to play your animation.

    So in you first Update call you call Animator.Play and then in your next Update call the state should be the new state.
     
  5. tosiabunio

    tosiabunio

    Joined:
    Jun 29, 2010
    Posts:
    115
    Thanks for a quick reply!

    Okay, another approach then (cut from Update()):
    Code (CSharp):
    1.         var info = animator.GetCurrentAnimatorStateInfo(0);
    2.         if (currentAnimState != info.nameHash) {
    3.             Debug.LogWarning("Different state than expected");
    4.         }
    5.         if (currentAnimState != newState) {
    6.             animator.Play(state, -1, 0f);
    7.             currentAnimState = state;
    8.         }
    New state is only played if it differs from the previous (stored) state. But it seems that sometimes the stored state is different then the state actually playing.

    I expect the problem to be somewhere in my code as this affects only objects generated by one of 2 otherwise identical generators. I'm just looking for suggestions where to look.
     
  6. tosiabunio

    tosiabunio

    Joined:
    Jun 29, 2010
    Posts:
    115
    Okay, found the problem and it was indeed related to my code - negative scale reversed my characters so animations were played wrongly. The states changed correctly though - did some debugging to verify that.

    Edit: some animation changed scale to negative but others didn't reset it back to positive hence the discrepancy between the state playing and the visual effect.
     
    Last edited: Jan 9, 2015
    Mecanim-Dev likes this.
  7. gamegirl1984

    gamegirl1984

    Joined:
    Nov 6, 2014
    Posts:
    102
    Hey so in know this is a very old post but would you please post the answer to your question?? i'm running in same issues. I cannot get my animator animation to play. I am use to legacy and i read and watched many videos and tutorials but i just need "on collison enter, play animation from the animator controller. that is all."
     
  8. undead504

    undead504

    Joined:
    Apr 7, 2015
    Posts:
    2
    AnyBody with the Golden Answer because unity does not have much on the matter
     
  9. Owlbear_Headspin

    Owlbear_Headspin

    Joined:
    Jun 25, 2016
    Posts:
    6
    I've been googling for hours trying to figure this out.
     
  10. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Not sure what is the question.
    What are you trying to figure out?
     
  11. ninjapretzel

    ninjapretzel

    Joined:
    Jul 19, 2011
    Posts:
    27
    I'm going to necro this thread because I think I understand the problems these people are having with mecanim.

    With mecanim being off of states, there's no way to directly play an animation, and override animations that are currently playing (like was possible in the legacy animation system). They want to start playing some animation from code, with a function call at some point, without a state being set up for the animation they want to play.

    If mecanim is still being maintained, it would be very useful to have a function which allows an animation to just be played from code. Something with the following signature:
    Play(AnimationClip animation, int layer)
    which overrides animations playing on the given layer with the animation clip, and when the animation is finished, resets the layer to the default state.

    I have had many situations where I need to have a lot of animations in a character, and it would be much easier to load a bunch of animations into an array, and simply play the animations via code based on circumstance, rather than setting up a state machine and hundreds of transitions and parameters to manage which animation is playing. The state machine is nice for certain things (like blending between directional running), but very prohibitive when there are a large number of animations that need to be played, in many different situations.

    On top of that, it would be nice to be able to instantly transition into another animation while one is playing on that layer.
    Example: A character may be able to dodge-roll during many different animations. It would be convenient to override a layer which may or may not be playing certain animations, to play the dodge-roll animation, and then return to an 'empty' state after the dodge roll completes.

    Maybe even have a variant of Play with the following signature
    Play(AnimationClip animation, int layer, float transitionTime)

    I hope that this is easier to understand than previous responses in this thread.
     
    sub111 and Thorlar like this.
  12. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    @ninjapretzel

    I'm not a big fan of Mecanim (in fact the only thing i'm like is the retargeting), but a lot things are doable by code with few functions..

    Exemple of Animator Controller


    Example of W.I.P code. Only Animator.Play or Animator.CrossFade are used :
    Code (csharp):
    1.  
    2.     void InitMove(bool avant) {// ==================================================================
    3.  
    4.        IsWalk     = !IsRun;
    5.        turnSpeed  = baseTurnSpeed;
    6.        IsBack     = !avant;
    7.  
    8.        if (!IsBack) { // move forward !!!!!!!!!!!!!!!!!!!!!!
    9.            if (IsCrouch) { // Crouch !!! +++++++++++++++++++++++++++++++++++
    10.                IsWalk = false;
    11.                IsRun  = false;
    12.                if (IsArmed) {
    13.                    AnmName  = "RIFLE_CROUCHSTART";
    14.                    AnmDuree = 0.6f;
    15.                    AnmSpeed = 1.5f; // a voir !!!
    16.                    AnmSpeedDelais = 0.05f;
    17.                    AnmNEXT = "RIFLE_CROUCH";
    18.                }
    19.                else {// not armed
    20.                    AnmName  = "CROUCHSTART";
    21.                    AnmDuree = 0.600f;
    22.                    AnmSpeed = 1.5f;  // a voir !!!
    23.                    AnmSpeedDelais = 0.05f;
    24.                    AnmNEXT = "CROUCH";
    25.                }
    26.            } else {// Not Crouch !!! +++++++++++++++++++++++++++++++++++++++
    27.                if (IsArmed) {
    28.                    if (IsWalk) {
    29.                        AnmName  = "RIFLE_WALKSTART";
    30.                        AnmDuree = 0.733f;
    31.                        AnmSpeed = 2.0f;  // a voir !!!
    32.                        AnmSpeedDelais = 0.10f;
    33.                        AnmNEXT = "RIFLE_WALK";
    34.                    }
    35.                    if (IsRun) {
    36.                        AnmName  = "RIFLE_RUNSTART";
    37.                        AnmDuree = 0.633f;
    38.                        AnmSpeed = 4.0f;  // a voir !!!
    39.                        AnmSpeedDelais = 0.2f;
    40.                        AnmNEXT = "RIFLE_RUN";
    41.                        turnSpeed  = baseTurnSpeed * 2.0f; // a voir !!!
    42.                    }
    43.                } else {// not crouch, not armed
    44.                    if (IsWalk) {
    45.                        AnmName  = "WALKSTART";
    46.                        AnmDuree = 0.767f;
    47.                        AnmSpeed = 2.0f; // a voir !!!
    48.                        AnmSpeedDelais = 0.10f;
    49.                        AnmNEXT = "WALK";
    50.                    }
    51.                    if (IsRun) {
    52.                        AnmName  = "RUNSTART";
    53.                        AnmDuree = 0.767f;
    54.                        AnmSpeed = 4.0f; // a voir !!!
    55.                        AnmSpeedDelais = 0.2f;
    56.                        AnmNEXT = "RUN";
    57.                        turnSpeed  = baseTurnSpeed * 2.0f; // a voir !!!
    58.                    }
    59.                } // not crouch, not armed
    60.            } // Not Crouch !!! +++++++++++++++++++++++++++++++++++++++++++++
    61.        } else // mouvement arriere !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    62.        {
    63.            if (IsCrouch) { // Crouch !!! +++++++++++++++++++++++++++++++++++
    64.                if (IsArmed) {
    65.                    AnmName  = "BK_RIFLE_CROUCHSTART";
    66.                    AnmDuree = 0.6f;
    67.                    AnmSpeed = 1.0f; // a voir !!!
    68.                    AnmSpeedDelais = 0.05f;
    69.                    AnmNEXT = "BK_RIFLE_CROUCH";
    70.                }
    71.                else {// not armed
    72.                    AnmName  = "BK_CROUCHSTART";
    73.                    AnmDuree = 1.033f;
    74.                    AnmSpeed = 1.0f;  // a voir !!!
    75.                    AnmSpeedDelais = 0.05f;
    76.                    AnmNEXT = "BK_CROUCH";
    77.                }
    78.            } else {// Not Crouch !!! +++++++++++++++++++++++++++++++++++++++
    79.                IsWalk = true;
    80.                IsRun  = false;
    81.                if (IsArmed) {
    82.                    AnmName  = "BK_RIFLE_WALKSTART";
    83.                    AnmDuree = 1.067f;
    84.                    AnmSpeed = 2.0f;  // a voir !!!
    85.                    AnmSpeedDelais = 0.10f;
    86.                    AnmNEXT = "BK_RIFLE_WALK";
    87.                } else {// not crouch, not armed
    88.                    AnmName  = "BK_WALKSTART";
    89.                    AnmDuree = 0.833f;
    90.                    AnmSpeed = 2.0f; // a voir !!!
    91.                    AnmSpeedDelais = 0.10f;
    92.                    AnmNEXT = "BK_WALK";
    93.                } // not crouch, not armed
    94.            } // Not Crouch !!! +++++++++++++++++++++++++++++++++++++++  
    95.        } // mouvement arriere !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    96.  
    97.  
    98.        ImInIdle   = false;
    99.        ICanStartMove = false; // DeActiver Move
    100.        animRobot.CrossFade(AnmName, 0.05f, -1, CrossFadeTempo); // pas touche !!!
    101.        //animRobot.Play(AnmName);
    102.        _Invoke(_OnInitSpeed, AnmSpeedDelais);
    103.        _Invoke(_OnNextMove,  AnmDuree); // Delais de la prochaine animation
    104.    }
    105.  
    106.    void InitSpeed() { // ===========================================================================
    107.        is_OnInitSpeed = false; // timer eventuel
    108.        Speed = AnmSpeed;
    109.        if(IsBack) Speed = -Speed;
    110.    }
    111.  
    112.    void NextMove() {
    113.        is_OnNextMove = false; // timer eventuel !!!
    114.  
    115.        //animRobot.CrossFade( AnmNEXT, TimeToBlend, -1, CrossFadeTempo);
    116.        animRobot.Play(AnmNEXT);
    117.        ICanStopMove  = true;  // Activer Stop
    118.        ICanBlendMove = true;
    119.    }
    120.  
    121.    void StopMove() { // =============================================================================
    122.        //Transform toto = animRobot.GetBoneTransform(HumanBodyBones.LeftFoot);
    123.        //Debug.Log(Pg + " Pied " + toto.position );
    124.        Pg = PiedGauche.position.y;
    125.        Pd = PiedDroit.position.y;
    126.  
    127.        if (!IsBack) { // mouvement avant !!!!!!!!!!!!!!!!!!!!!!
    128.            if (IsArmed) {
    129.                // Anim mode Armed
    130.                if (IsWalk){
    131.                    AnmStopDelais = 0.6f;
    132.                    AnmIdleDelais = 0.9f;
    133.                    if (Pg > Pd) animRobot.CrossFade("RIFLE_STOP_WALK_GAUCHE", 0.70f, -1, CrossFadeTempo);
    134.                    else         animRobot.CrossFade("RIFLE_STOP_WALK_DROIT",  0.70f, -1, CrossFadeTempo);
    135.                }
    136.                if (IsRun) {
    137.                    AnmStopDelais = 0.4f;
    138.                    AnmIdleDelais = 0.8f;
    139.                    if (Pg > Pd) animRobot.CrossFade("RIFLE_STOP_RUN_GAUCHE", 0.70f, -1, CrossFadeTempo);
    140.                    else         animRobot.CrossFade("RIFLE_STOP_RUN_DROIT",  0.70f, -1, CrossFadeTempo);
    141.                }
    142.                if (IsCrouch){
    143.                    AnmStopDelais = 0.1f;
    144.                    AnmIdleDelais = 0.35f;
    145.                    if (Pg > Pd) animRobot.CrossFade("RIFLE_STOP_CROUCH_GAUCHE", TimeToCrouchIdle, -1, CrossFadeTempo);
    146.                    else         animRobot.CrossFade("RIFLE_STOP_CROUCH_DROIT",  TimeToCrouchIdle, -1, CrossFadeTempo);
    147.                }
    148.            } else
    149.            {   // Anim mode "Civil"
    150.                if (IsWalk) {
    151.                    AnmStopDelais = 0.6f;
    152.                    AnmIdleDelais = 0.9f;
    153.                    if (Pg > Pd) animRobot.CrossFade("STOP_WALK_GAUCHE", 0.70f, -1, CrossFadeTempo);
    154.                    else         animRobot.CrossFade("STOP_WALK_DROIT",  0.70f, -1, CrossFadeTempo);
    155.                }
    156.                if(IsRun) {
    157.                    AnmStopDelais = 0.4f;
    158.                    AnmIdleDelais = 0.8f;
    159.                    if (Pg > Pd) animRobot.CrossFade("STOP_RUN_GAUCHE", 0.70f, -1, CrossFadeTempo);
    160.                    else         animRobot.CrossFade("STOP_RUN_DROIT",  0.70f, -1, CrossFadeTempo);
    161.                }
    162.                if (IsCrouch) {
    163.                    AnmStopDelais = 0.1f;
    164.                    AnmIdleDelais = 0.35f;
    165.                    if (Pg > Pd) animRobot.CrossFade("STOP_CROUCH_GAUCHE", TimeToCrouchIdle, -1, CrossFadeTempo);
    166.                    else         animRobot.CrossFade("STOP_CROUCH_DROIT",  TimeToCrouchIdle, -1, CrossFadeTempo);
    167.                }
    168.            }
    169.        } else // mouvement arriere !!!!!!!!!!!!!!!!!!!!!!
    170.        {
    171.            if (IsArmed) {
    172.                // Anim mode Armed
    173.                if (IsWalk){
    174.                    AnmStopDelais = 0.6f;
    175.                    AnmIdleDelais = 0.9f;
    176.                    if (Pg > Pd) animRobot.CrossFade("BK_RIFLE_STOP_WALK_GAUCHE", 0.70f, -1, CrossFadeTempo);
    177.                    else         animRobot.CrossFade("BK_RIFLE_STOP_WALK_DROIT",  0.70f, -1, CrossFadeTempo);
    178.                }
    179.                if (IsCrouch){
    180.                    AnmStopDelais = 0.1f;
    181.                    AnmIdleDelais = 0.35f;
    182.                    if (Pg > Pd) animRobot.CrossFade("BK_RIFLE_STOP_CROUCH_GAUCHE", TimeToCrouchIdle, -1, CrossFadeTempo);
    183.                    else         animRobot.CrossFade("BK_RIFLE_STOP_CROUCH_DROIT",  TimeToCrouchIdle, -1, CrossFadeTempo);
    184.                }
    185.            } else
    186.            {   // Anim mode "Civil"
    187.                if (IsWalk) {
    188.                    AnmStopDelais = 0.6f;
    189.                    AnmIdleDelais = 0.9f;
    190.                    if (Pg > Pd) animRobot.CrossFade("BK_STOP_WALK_GAUCHE", 0.70f, -1, CrossFadeTempo);
    191.                    else         animRobot.CrossFade("BK_STOP_WALK_DROIT",  0.70f, -1, CrossFadeTempo);
    192.                }
    193.                if (IsCrouch) {
    194.                    AnmStopDelais = 0.1f;
    195.                    AnmIdleDelais = 0.735f;
    196.                    if (Pg > Pd) animRobot.CrossFade("BK_STOP_CROUCH_GAUCHE", TimeToCrouchIdle, -1, CrossFadeTempo);
    197.                    else         animRobot.CrossFade("BK_STOP_CROUCH_DROIT",  TimeToCrouchIdle, -1, CrossFadeTempo);
    198.                }
    199.            }      
    200.        } // mouvement arriere !!!!!!!!!!!!!!!!!!!!!!
    201.  
    202.        _Invoke(_OnStopVitesse, AnmStopDelais);
    203.        _Invoke(_OnIdleMove, AnmIdleDelais);
    204.    }
    205.  
     
    Last edited: Jul 9, 2017