Search Unity

When respawning, why doesn't Animator.Play work?

Discussion in 'Animation' started by jerotas, Mar 2, 2014.

  1. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    Hi, I've just started using Mechanim and so far I don't like it because it doesn't appear to work properly in the following situation. I use pooling (Pool Manager). I have a coffin prefab with 2 animations: "idle" and "open coffin". There are zero transitions. By script I trigger the open coffin like so:

    Code (csharp):
    1. var anim = this.GetComponent<Animator>();
    2. anim.Play("Open");
    3.  
    Then when you beat the level, all the coffins despawn. When they respawn on the next level, I want them to show as closed (idle animation), so I do this code in OnSpawned (which fires when the object spawns):

    Code (csharp):
    1. anim.Play("Idle");
    However what I see is that the coffin is still open, visually. If I select the coffin in the Scene and open the Animator window however, it shows that the idle animation is running and looping. Huh? Why would it behave like this, and how exactly do I make things respawn in the default animation state? Not using pooling is not an option because this is a mobile game.

    Is this a bug? I might as well use legacy animations. They at least work properly.

    Despawning really is just turning a game object disabled. Spawning is just turning a game object enabled. If that helps?
     
    Last edited: Mar 2, 2014
  2. dreasgrech

    dreasgrech

    Joined:
    Feb 9, 2013
    Posts:
    205
    After you spawn the object from the pool, try turning its gameObject off and then back on again and see if that resets the Animator.

    If that doesn't work, try adding the Animator component dynamically after spawning the object from the pool (make sure you obviously delete the previous Animator)

    In my game, after spawning a character model from the pool, I had to first add the Animator component to it and set the runtimeAnimatorController and avatar properties, then turn the gameObject off and on again, and then I finally set the layer weights.

    This is the gist of the code I use:

    Code (CSharp):
    1. var modelObject = modelsSpawnPool.Spawn(modelPrefab);
    2. modelObject.transform.parent = transform;
    3. modelObject.transform.localRotation = Quaternion.identity;
    4. modelObject.transform.localPosition = Vector3.zero;
    5.  
    6. var animator = modelObject.AddComponent<Animator>();
    7. animator.applyRootMotion = false;
    8. animator.runtimeAnimatorController = theAnimatorController;
    9. animator.avatar = theModelAvatar;
    10.  
    11. /* This hack is needed otherwise the animation doesn't start... */
    12. gameObject.SetActive(false);
    13. gameObject.SetActive(true);
    14. /* End hack */
    15.  
    16. // Set the Animator Layer weights
    17. animator.SetLayerWeights(2, 1); // just an extension method to set Animator layers
     
  3. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    Thanks, I will try that when I have some time (working on a different game right now and I wasn't doing Mechanim properly before).