Search Unity

  1. We would like to hear your feedback about Unity and our products. Click here for more information.
    Dismiss Notice

Get the middle result of animation layer mixing?

Discussion in 'Animation' started by teighshiclbw, May 14, 2019.

  1. teighshiclbw

    teighshiclbw

    Joined:
    Jun 26, 2018
    Posts:
    33
    1557713074151.png
    Animator has 3 layers:Layer0、Layer1、Layer2
    I need to get rotation of head bone in 3 diffrent situations:
    1、Only Layer0
    2、Layer0 mix with Layer1
    3、Layer0 mix with Layer1 and then mix with Layer2
    Code (CSharp):
    1. Transform head = animator.GetBoneTransform(HumanBodyBones.Head);
    2. animator.SetLayerWeight(0, 1);
    3. animator.SetLayerWeight(1, 0);
    4. animator.SetLayerWeight(2, 0);
    5. animator.Update(0);
    6. Quaternion headRotation1 = head.rotation;
    7.  
    8. animator.SetLayerWeight(0, 1);
    9. animator.SetLayerWeight(1, 1);
    10. animator.SetLayerWeight(2, 0);
    11. animator.Update(0);
    12. Quaternion headRotation2 = head.rotation;
    13.  
    14. animator.SetLayerWeight(0, 1);
    15. animator.SetLayerWeight(1, 1);
    16. animator.SetLayerWeight(2, 1);
    17. animator.Update(0);
    18. Quaternion headRotation3 = head.rotation;
    Code above can achieve the goal.
    But it execute Animator.Update() 3 times every frame, this method has seriously impact on performance.
    I don't know Unity's source code, my guess is that when Animator.Update() executed, Unity calculate Layer0 first, and then base on that, mix with Layer1, and then base on previously result, mix with Layer2.
    So it is possible to get rotation of head bone in 3 diffrent situations in only ONE Animator.Update().
    But I don't know if it is possible in current version Unity.

    Or is there any other method can achieve the same goal?
     
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    3,875
    You could have three copies of the head bone with the same animation curves. Then you'd mask out copy 2 and 1 in layer 1, copy 1 in layer 2, and have no mask in layer 3.

    That won't work with humanoid remapping, so it might not be applicable. What are you trying to do?
     
  3. teighshiclbw

    teighshiclbw

    Joined:
    Jun 26, 2018
    Posts:
    33
    This will work, but it need to change skeleton hierachy, and not only head, I might need to get rotation of arms, legs, etc. So it's too tedious,not a acceptable method.
    Just tring to solve this problem.
    https://forum.unity.com/threads/blend-animation-and-recalculate-some-bones-rotation.676465/

    I am not familiar with Animation C# Jobs, do you think it will help?
    https://blogs.unity3d.com/2018/08/27/animation-c-jobs/
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    3,875
    Animation C# jobs allow you to do things as a part of the animation stream. It does require using at least 2018.2, though - you seem to be using 5.6 from the other thread.

    I think there might be some extra overhead from doing animator.Update(0); that you wouldn't get from just running the animation, as it requires the entire animation to happen immediately on the main thread instead of letting it run on the animation thread. Try having several copies of your model playing the same animations as your main model, just with different settings, and read off their current positions. That should probably be a lot faster than doing what you're doing now.
     
  5. teighshiclbw

    teighshiclbw

    Joined:
    Jun 26, 2018
    Posts:
    33
    Yes, this also work, but still strange and 3 models running at the same time still cause performance problem.
    I can switch to 2018.2 if Animation C# jobs does help, just trying to figure it out.