Bone manipulation in State Machine Behaviours?

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:

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        Transform testBone = animator.GetBoneTransform(HumanBodyBones.Spine);
       
        Debug.Log(string.Format("Bone {0}: {1}", testBone.name, testBone.rotation));
       
        testBone.rotation = Quaternion.identity;
       
        Debug.Log(string.Format("Bone {0}: {1}", testBone.name, testBone.rotation));
    }

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.

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.

1 Like

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.

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.

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.