Search Unity

Update Bone Positions After Animation with "Animate Physics"

Discussion in 'Animation' started by DDNA, Sep 20, 2016.

  1. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    I want to change the bone positions in script after the animation runs. This works fine if I put this code in LateUpdate. But I need to run my animator with "Animate Physics" so as far as I understand the animation is running in the FixedUpdate cycle. Sine there is no LateFixedUpdate there is no place for this code to be.

    What is the right way to do this?
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Could you give us a little bit more information on what you are trying to achieve?
    How are you going to move this bone? with a physic force or simply set a new position?

    Are you trying to implement a ragdoll to animation blending?
     
  3. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    >Are you trying to implement a ragdoll to animation blending?

    Yes this.

    I am running 2 skeletons and blending them. One with animation and one with a Ragdoll. I am blending them but at some point I will probably want to mask off bones to have them be controlled by animation or ragdoll.
     
  4. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    I don't understand why Unity is so stubborn about adding a LateFixedUpdate it is something people have been asking for years.
     
  5. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    PrasadPDC likes this.
  6. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    If you take this example and change the animator to "Animate Physics" it doesn't work anymore.



    This is because what he is doing in LateUpdate now needs to be done in the Fictional LateFixedUpdate. Which is really the point of the question.

    We found a "solution" to this. We have this kludgey system in-place to deliver a LateFixedUpdate, using some bizarre use of a yeild statement to force unity to give us an opportunity to do something after the animator. We had this in place already because we needed a LateFixedUpdate for other things. It sucks that Unity can't just provide this and we have to resort to things like this. It leaves me in fear that this side effect behavior will stop working at some point.
     
  7. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    well that sucks, effectively it seem there is no way right now to fix this issue and honestly the current solution to blend from physic to animation is way to complex.

    I will bring this to the animation team meeting and we will find a better solution.
    As for the LateFixedUpdate I will talk with the scripting team to get their thought about this one.
     
    awesomedata likes this.
  8. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    Thank you so much.
     
  9. alice_funo

    alice_funo

    Joined:
    Mar 9, 2016
    Posts:
    14
    I'm also having the same problem since we have to use AnimatePhysics mode (it's a hard requirement for our game).

    The way I have tried to rig it, is to have a "PostFixedUpdate" function that is called before every FixedUpdate and Update -- only if a FixedUpdate has occurred (evident by using timestamps). I still have to keep some timestamps because everything called inside PostFixedUpdate cannot rely on Time.deltaTime anymore (we don't know if we have multiple updates in a row, or fixed updates in a row, etc).

    In short, it will be really nice to have a callback *after* animation is done, so we can apply things like procedural rotations and full body IK
     
  10. Sokharev

    Sokharev

    Joined:
    Oct 10, 2013
    Posts:
    7
    Hello, i've faced the same problem(but not for ragdolls) and tried following to deal:
    1. add StateMachineBehaviour to your states where you're need PostFixedUpdate
    2. add your code to OnStateUpdate section
    3. profit(?!)(perhaps?)
    Actually it doesn't solved my problem, but as i see in "Timeline" section of profiler it doing update exactly after "animations" update(when you're in PhysicsUpdate mode) - so _may_ be it can be ok for you.
     
    Last edited: Nov 24, 2016
  11. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Well yes the OnStateUpdate will be called after the Animation Update but the the animation system has not yet written all the animated values to unity so you can't override the values in this callback.

    But we are currently changing the animation system to behave more correctly with physic. Rather than overriding animation values in a LateFixedUpdate we want to add a new blending phase after the physic update.
     
  12. Sokharev

    Sokharev

    Joined:
    Oct 10, 2013
    Posts:
    7
    Nice to hear, any suggestions on release time?
     
  13. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    I can tell you that it won't be in 5.6, maybe the next release after if everything goes well
     
  14. Malbers

    Malbers

    Joined:
    Aug 7, 2015
    Posts:
    2,558
    Hi guys, well its good to find this :)

    because Im having this problem since forever, accidentally discover that it was because I was using Animate Physics mode, on update mode works fine but again I need the Animate Physics mode to my characters, and the get the same strange behaviour as @DDNA ..

    @Mecanim-Dev any new hints on this? same issue on all unity versions :)
     
  15. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The feature is currently in developpement, so it going forward but I have no idea when it will be available yet.
     
    awesomedata and Malbers like this.
  16. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419

    Is this coming with the new Timeline system, or is it still in the planning phases?

    I am working on something that needs to be tied closely to physics (but not rely on it entirely) and I'd really prefer to know how performant this will be in Unity if I have to roll my own solution with manually setting transforms.

    Here's what I've gotta implement in Unity, and I've got to have bone-level physics control to do it:

    http://www.gdcvault.com/play/1020583/Animation-Bootcamp-An-Indie-Approach

    Any thoughts on a good performant approach to spring physics and secondary motions being combined with the custom blending curve interpolation necessary to achieve what's in that video inside of Unity, @Mecanim-Dev ?
     
  17. Malbers

    Malbers

    Joined:
    Aug 7, 2015
    Posts:
    2,558
    After 3 long years of beating me I found a solution!!!!
    OMG I'm so HAPPY!!

    Just a simple line of Code and no more jittering

    On Late Update
    just call the Animator.Update(0f);
    this will update all the bones positions and rotations using the animation is playing
    after that you can make the modifications you need.

    Here's a simple example script on how to use it:
    You just need to set the Animator to animate physics:
    Code (CSharp):
    1. using UnityEngine;
    2.     public class ModifyBoneInFixedUpdate : MonoBehaviour
    3.     {
    4.         public bool animatePhysics;
    5.         public Animator anim; //Reference of the animator
    6.         public Transform bone;      //Bone to modify                            
    7.         public Vector3 offset = new Vector3(0,90,0); //offset to apply to the bone
    8.         [Range(0,1)]
    9.         public float Weight = 1;
    10.  
    11.         void LateUpdate()
    12.         {
    13.             if (animatePhysics)
    14.             anim.Update(0);
    15.  
    16.             bone.rotation = Quaternion.Lerp(bone.rotation, bone.rotation * Quaternion.Euler(offset), Weight);
    17.         }
    18.     }
    19.  
    Thank you and good night! :cool::p
     

    Attached Files:

    Last edited: Jan 25, 2020
    joshcamas and Ruberta like this.
  18. Punfish

    Punfish

    Joined:
    Dec 7, 2014
    Posts:
    401
    That code was causing some really weird behavior, the entire animator seemed a little fast. I don't imagine it's great for performance either.

    My problem was that I wanted to apply an IK offset to animation default, but wasn't able to without jitter. I was able to solve this problem by getting the '_lastBonePosition/Rotation' as well the '_lastTransformPosition/Rotation' in OnAnimatorIK. Then I would apply the offset to _lastBonePos/Rot while adding in the current transform position/rot difference.

    Example:
    Code (CSharp):
    1.         private void OnAnimatorIK(int layerIndex)
    2.         {
    3.             if (layerIndex != 0)
    4.                 return;
    5.  
    6.             _lastIKRootPosition = transform.position;
    7.             _lastIKRootRotation = transform.rotation;
    8.  
    9.             if (_leftHandBone != null)
    10.             {
    11.                 _lastLeftHandPosition = _leftHandBone.position;
    12.                 _lastLeftHandRotation = _leftHandBone.rotation;
    13.             }
    14.             if (_rightHandBone != null)
    15.             {
    16.                 _lastRightHandPosition = _rightHandBone.position;
    17.                 _lastRightHandRotation = _rightHandBone.rotation;
    18.             }
    19.         }
    20.  
    21. UpdateToSpring(_leftSolver.solver, _lastLeftHandPosition, _lastLeftHandRotation, _leftPositionSpring, _leftRotationSpring);
    22.  
    23.         private void UpdateToSpring(IKSolverLimb solver, Vector3 startPos, Quaternion startRot, Spring positional, Spring rotational)
    24.         {
    25.             solver.target.position = (transform.position - _lastIKRootPosition) + startPos + _weaponDetailsHandler.transform.TransformDirection(positional.Value);
    26.             solver.target.rotation = (transform.rotation * Quaternion.Inverse(_lastIKRootRotation)) * startRot * Quaternion.Inverse(Quaternion.Euler(rotational.Value));
    27.             solver.Update();
    28.         }
     
    Malbers likes this.
  19. Marko_Esh

    Marko_Esh

    Joined:
    Nov 3, 2019
    Posts:
    2
    Dude, your`are awesome. Thanks, it works!
     
    joshcamas and Malbers like this.
  20. Develax

    Develax

    Joined:
    Nov 14, 2017
    Posts:
    67
    What is its current status, has it been implemented?
     
    SuppleTeets likes this.
  21. PrasadPDC

    PrasadPDC

    Joined:
    Jan 26, 2020
    Posts:
    3
  22. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,278
    This works for me! Absolutely fantastic!