Search Unity

  1. The 2022.1 beta is now available for testing. To find out what's new, have a look at our 2022.1 beta blog post.
    Dismiss Notice

Set State to last frame of animation / Save position of animation?

Discussion in 'Animation' started by BTStone, Oct 27, 2014.

  1. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,269
    Hey there!

    I've got some questions regarding the Mecanim-Animation System.

    So this is my basic setup:

    I've got my character on the left and a Sprite (2D Toolkit) on the right. It's got a Trigger on it, when the character enters the trigger the Tree-Sprite is going to fall down to the right.
    I accomplish that with an animation of the tree.

    The animator has two States:
    1) Idle
    2) FallDown

    While in Idle nothing happens. A Script attached to the Sprite-Objects checks if the Trigger is entered, and if so a bool variable "pushed" in the Animator is set to true, and if this condition is met Animator changes it's state from Idle to FallDown and in FallDown the Animation is played.

    Here's the setup:



    It starts in Idle and does nothing till the bool "pushed" is set to true via script.




    When the condition is met, the animation is played:
    (the animation is only played once, it's looping because this is a .gif file :p )




    Since the animation is not set to loop, the animation isn't looping, but the state itself is of course:



    This is working great. I just want to achieve something specific. I want the level to "memorize" that the tree falled down, meaning when the tree falls down, I want to save it's position and rotation.

    When the animation is finished, I save it's position/rotation. In the Awake() method I'm checking if the variables exist, and then I load them, so on level-load the tree is automatically set to it's fallen position/rotation.

    And that's the part where the problem comes in: it kind of works.
    The thing is, when the animation is finished it does save the new position/rotation, but on level load it doesn't load the new position but the old initial one. And this happens because the Animator-State is set again to Idle.

    It only works when I disable the animator when checking for the save-file.

    I'm using the Easy Save 2 Plugin to save the Transform btw.

    Here's the script I'm using:

    Code (CSharp):
    1. public class PushTree : MonoBehaviour
    2. {
    3.     public Animator anim;
    4.  
    5.     public Transform treeTransform;
    6.  
    7.     void Awake()
    8.     {
    9.         if(ES2.Exists("tree"))
    10.         {
    11.             Debug.Log("Tree loaded");
    12.             anim.enabled = false;
    13.             ES2.Load<Transform>("tree", treeTransform);
    14.         }
    15.         else
    16.         {
    17.             Debug.Log("Nothing to load!");
    18.         }
    19.     }
    20.  
    21.     void Start()
    22.     {
    23.         StartCoroutine(SaveState());
    24.     }
    25.  
    26.  
    27.     void OnTriggerEnter(Collider other)
    28.     {
    29.         if(other.gameObject.tag == "PlayerHitBox")
    30.         {
    31.             anim.SetBool("pushed", true);
    32.         }
    33.     }
    34.  
    35.  
    36.     IEnumerator SaveState()
    37.     {
    38.         while(true)
    39.         {
    40.             if(anim.GetBool("pushed"))
    41.             {
    42.                 yield return new WaitForSeconds(3.0f);
    43.  
    44.                 ES2.Save(treeTransform, "tree");
    45.                 Debug.Log("saved");
    46.  
    47.                 break;
    48.             }
    49.  
    50.             yield return null;
    51.         }
    52.     }
    53. }
    So I would like to know what I have to do with my states to have the same result without disabling my animator?
     
  2. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    BTStone likes this.
  3. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,269
    Thanks for the reply.

    I guess you mean:

    Code (CSharp):
    1. int has = Animator.StringToHash("FallDown");
    Yeah, I already tried that, but this will only play the animation again! I don't wan't to play the animation again, I want it to stay at the exact position/rotation of the last frame of the animation (when it's laying on the ground) when loading again.

    And apparently this only works when disabling the animator in Awake().
    I'm fine doing it that way, but I just wanted to know if there's a more elegant way to do so with Mecanim/Animations itself, since I use Mecanim for the very first time since yesterday :D
     
  4. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    I really mean hash, it the hashed name see function Animator.StringToHash("FallDown");
    And function Animator.Play use the hashed name to reference the state rather than the name to avoid using string.

    You can set your state time to 1 if you don't want to replay the animation
    anim.Play(hash, 0, 1.0F);
     
    richardfu71 and theANMATOR2b like this.
  5. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,269
    Ah sorry, a typo. I did get you, though.

    Ah! Setting the state-time to 1.0f did the job! Thanks! :D
     
  6. SanthanaBharathy

    SanthanaBharathy

    Joined:
    Oct 6, 2012
    Posts:
    77
    Will it stop the animation to the endFrame
     
unityunity