Search Unity

Using StateMachineBehaviours for procedural animation

Discussion in 'Animation' started by Zergling103, Jul 23, 2015.

  1. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    I tried writing a state machine behaviour for procedural animation. As a simple test, within OnStateUpdate(), I grabbed a bone (such as the head bone) and set its rotation to a random rotation.

    The expected behaviour is that the characters head would twitch out, but it doesn't seem to move at all.
    There is only one state and one layer in the animator.

    I've also tried using OnStateMove(), but this also didn't work.

    Is there something I'm doing wrong, or is this not an intended usage?
     
    Last edited: Jul 23, 2015
  2. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
  3. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    I've just tested it - unfortunately that doesn't work either.
     
  4. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Is the head under IK control? According to the docs, the call order is:
    1. MonoBehaviour.OnAnimatorIK()
    2. StateMachineBehaviour.OnStateIK()
    3. Mecanim's internal IK
    So if Mecanim applies any IK to the head in step #3, it'll overwrite any work you did in #2.
     
  5. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    I don't think it is. At least not explicitly. Technically, IK isn't applied to the head - it can apply look rotation though, which would affect this step... But I didn't enable it.

    I'll try affecting a different bone, like... the arm or the jawbone.
     
  6. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    I made it so that in OnStateIK(), EVERY bone is randomly rotated. No motion whatsoever.


    override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    for (int i = 0; i < (int)HumanBodyBones.LastBone; i++)
    {
    var bone = animator.GetBoneTransform((HumanBodyBones)i);

    if(bone != null)
    bone.rotation = Random.rotation;
    }
    }
     
  7. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Are you sure the controller is in this state? If you add some Debug.Log lines, do they write to the console? Does your method signature exactly match the one below?

    void OnStateIK(Animator animator, AnimatorStateInfo animatorStateInfo, int layerIndex)