Search Unity

Bone manipulation in State Machine Behaviours?

Discussion in 'Animation' started by TravisEpic, Mar 30, 2015.

  1. TravisEpic

    TravisEpic

    Joined:
    Jul 24, 2012
    Posts:
    2
    In my current project I am manipulating animator bones in LateUpdate after the internal animation update happens. This allows me to use animations while doing some FK on the skeleton. This works rather well but I have to manually script when the FK should take over on a per animation state basis.

    Ideally I would be able to modify the skeleton on the Animator base layer then allow the animations to override them on higher layers taking advantage of AvatarMasks. I was really excited with the announcement of StateMachineBehaviours. As I assumed I could have a single state on the base layer and attach a script that does all the rotations/translations that I need. It seems as if the internal animation update runs after the StateMachinesBehaviours so all the changes are reset to what the default pose is.

    Test Script:
    Code (CSharp):
    1.     // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    2.     override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    3.     {
    4.         Transform testBone = animator.GetBoneTransform(HumanBodyBones.Spine);
    5.        
    6.         Debug.Log(string.Format("Bone {0}: {1}", testBone.name, testBone.rotation));
    7.        
    8.         testBone.rotation = Quaternion.identity;
    9.        
    10.         Debug.Log(string.Format("Bone {0}: {1}", testBone.name, testBone.rotation));
    11.     }
    This test script does show that I am able to modify the bone rotation values but it seems it is reset before LateUpdate()/Scene Rendering as the bone orientation never changes in scene.

    I'm interested in knowing if there is a way to achieve the desired effect.
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Hi Travis,

    this is an interresting question, for now as you have experienced this is not possible since OnStateUpdate is called while the animation is been processed. bone manipulation is only possible in a MonoBehaviour.LateUpdate

    We would need to add a new callback OnStateLateUpdate to allow user to do this. This is not on the road map yet but we will look at this.
     
    chelnok likes this.
  3. TravisEpic

    TravisEpic

    Joined:
    Jul 24, 2012
    Posts:
    2
    Thank you for the reply Mecanim.Dev. It is great to know this information so I don't keep pounding away at it. I will continue to use LateUpdate() in the meantime.
     
  4. TH_Unity

    TH_Unity

    Joined:
    Jul 9, 2013
    Posts:
    11
    Is this still impossible? It's somewhat hard to determine the begin and and of an animation. As I expect, the OnStateUpdate() is not called anymore when the animation has a weight of less than 50%? This would be another nice side effect. In addition the use of a state behaviour for bone manipulates perfectly encapsules an animation and its manipulation.
    Right now I am not sure how to properly simulate this "OnStateLateUpdate()" method. Any tips are appreciated.
     
  5. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    we haven't added this yet

    It should be always called until you get an OnStateExit which should be when the weight is 0

    unfortunately there is no good way to simulate the behaviour that you want.