Search Unity

Accessing Transform in an Animation

Discussion in 'Animation' started by tramelson, Sep 14, 2016.

  1. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
    Is there a way to access and set a GameObject's transform component in an animation (in a script)? Can I change an object's position at a specific time in the animation?
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Yes you can change the value of an animated transform component but you need to do it in LateUpdate() which is called after the animation update. If you do it in Update() your value gonna get override by the animation system
     
    thewall37 and azinicus like this.
  3. Shitoshy

    Shitoshy

    Joined:
    Sep 15, 2016
    Posts:
    2
    Hi, is there a way to make a reference to an expecific frame of an animation? I want to make a function that change the positiojn of my Collider2D when the animation pass the 3° frame, then change it again passing the 7 frame, the 10 frame, the 15 frame, and there....
     

    Attached Files:

  4. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
    Thank you for your response. How can I get/set the value of a position of an object at a specific time in the animation frame?
     
    anycolourulike likes this.
  5. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
  6. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
    I'm looking at the AnimatorStateInfo, but I don't see a variable for the position - so how would I be able to set this position at a certain time if I wanted to do so in a script?
     
  7. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    I would recomend you to use AnimationEvents as they are designed for this kind of operation but here the code in case you want to do it with polling.

    You need to poll the animator at each update and when normalizedTime is pass the specific time that you want you set the position on the transform that yout want.

    Code (CSharp):
    1. class MyMonoBehaviour : MonoBehaviour
    2. {
    3.     public GameObject myObject;
    4.     public Vector3 position;
    5.     void LateUpdate()
    6.     {
    7.         Animator animator = GetComponent<Animator>();
    8.         AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
    9.         float playbackTime = currentAnimatorStateInfo.normalizedTime * currentAnimatorStateInfo.length;
    10.         if (currentAnimatorStateInfo.IsName("MyState") && playbackTime > 0.3f)
    11.         {
    12.             myObject.position = position;
    13.         }
    14.     }
    15. }
     
    tramelson likes this.
  8. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
    Is LateUpdate() only used to change a position? What about if I know the positions at certain times in advance and just want to set them from the beginning - I'm guessing I wouldn't need to poll the animator in that case - so what would I use to code that?
     
  9. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    It depend if the position that you want to change is animated or not,

    If it animated it does mean that the animator will write a value at each Update call so you need to override the animated value in a LateUpdate() call/
    If it not animated then you can set the value once at the beginning and that it, you can do it in either Update() or Start() or LateUpdate() in this case it doesn't matter
     
  10. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
    Great, and how would I set the position values from the beginning (in a case where I'm not overriding)?
     
    anycolourulike likes this.
  11. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    something like this
    Code (CSharp):
    1.  
    2. class SetupPosition : MonoBehaviour
    3. {
    4.     public GameObject myObject;
    5.     public Vector3 myValue;
    6.  
    7.     void Start()
    8.     {
    9.         myObject.transform.position = myValue;
    10.     }
    11. }
     
  12. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
    Sorry I wasn't clear - I meant how would a set a position at a specific time (time I guess would be the animation time frame)?
     
  13. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
  14. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
    I'm trying to figure out a way to set specific positions at specific times - knowing that in advance (since I'll have an external data file with that information). So I'm trying to do something like this:

    1. class MyMonoBehaviour : BallPosition
    2. {
    3. void Start()
    4. {
    5. if (playbackTime == 0.3f) //where playbackTime is a time in the animation frame
    6. {
    7. this.transform.position = new Vector3(0, 0, 0);
    8. }
    9. else if (playbackTime == 0.4f)
    10. {
    11. this.transform.position = new Vector3(1, 0, 0);
    12. }
    13. //.....for multiple times in the animation frame
    14. }
    15. }
    So where would I get this playbackTime to set where the object would go at a certain time?
     
    anycolourulike likes this.
  15. tramelson

    tramelson

    Joined:
    Sep 6, 2016
    Posts:
    21
  16. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Code (CSharp):
    1.  
    2. AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
    3. float playbackTime = currentAnimatorStateInfo.normalizedTime * currentAnimatorStateInfo.length;
    4.  
    You cannot use the == operator, because there is no gurantee that you gonna get a tick exactly at 0.3f or 0.4f.

    But you should use animationevent in this case if you have a lot of timeline event in your animation clip.
     
    tramelson likes this.
  17. Capricornum

    Capricornum

    Joined:
    Feb 1, 2018
    Posts:
    22
    Hello,
    this discussion is a little old but I was hoping to find an answer here to a question I seem unable to grasp.

    I want a little Ball's transform.position to be animated. Starting at one Vector2, passing another and ending at a third. However the three Vector2 positions are different every time I play the animation on the ball. How do I access the balls animation every time I want but set the keyframes to different values?
    Thank you for support!