Search Unity

How to fix animation that doesn't have jaw bone?

Discussion in 'Animation' started by skinwalker, Oct 21, 2017.

  1. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    Hey everyone,

    I bought a mocap package from Kubold and the rig lacks a jaw bone. All of my other animations have jaw bones and it's used, so I don't want to remove it from my character's rig. What happens when I play an animation that doesnt have a jaw bone is that the character's mouth stays wide open. I have tried to reparent the lowerJaw to an empty game object at the start of the animation, but there's still a visible "switch" for less than 0.5 seconds, but you can see how the character's mouth goes up and then it's back in place.

    How do you deal with that kind of problems?
     
  2. Nateply

    Nateply

    Joined:
    May 20, 2014
    Posts:
    46
    On your prefab where you set the character up for humanoid or legacy, edit it (probably it's humanoid), there should be a green dot on the tip of the chin. Deselect that one and apply changes. Unity defaults to mouth open of there's no bone for it, so you need to disconnect it. I'm not at the computer, but am working from memory. Good luck!
     
  3. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    The dot is not green, it's grey and I am doing that to the rig that contains the animation without the jaw bone, as I said I don't want to disconnect the jaw bone from my main character, because it uses it for other animations.
     
  4. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    Any other suggestions?
     
  5. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Don't know if you can only isolate the jaw bone from the head for the mask to work properly, but if you can - Create a Jaw layer and have one of the animations that have the jaw bone animated closed in that layer. Create a layer or avatar ? mask to only effect the jaw bone.
    Set up the state machine to always play the jaw layer animation when the other animations that do not have the jaw animation play.
     
  6. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    So I made an avatar mask that has only the head selected and under Transform I imported the avatar of my character (with all of the bones), then I deselected all except the lowerjaw, I went to the animator controller, created a new Layer and increased its weight to 1 then checked sync and applied the new JawAvatarMask, I played the game and nothing has changed.

    The animation that I am playing is coming from a rig that does not have a jaw bone only head.

    One thing that I found out is, if I disable "Sync" and drag and drop the animation that lacks the jaw bone it seems like it's working, but then it uses a separate layer for the animations where I have to assign each state which is not what I would like.

    I think this won't work, because the other rig does not have a jaw bone at all.
     
    Last edited: Oct 23, 2017
  7. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    I found two solutions.

    1. As @theANMATOR2b suggested, I created an avatar mask which uses the original rig and only has the lower jaw selected + the head under the humanoid figure. You also need a new layer in the animator that always plays an animation where the character has its mouth closed, it's not set to sync and its set to override. The problem is that you have to set the weight of the second layer when you are playing an animation that doesn't have a jaw bone to 1 and then back to 0 (you probably want to lerp between 1-0).

    2. This is easier solution and performs better, basically one line of code, without doing anything else

    Code (CSharp):
    1.  void LateUpdate()
    2.     {
    3. _animator.GetBoneTransform(HumanBodyBones.Jaw).localRotation = Quaternion.Euler(0, 0, 0);
    4.     }
    You can also set the Quaternion's X to some other value if you want to open the mouth - 0 means closed. Disable that script if you are playing an animation that animates the jaw.
     
    JBR-games, ioFlow, jeromeWork and 6 others like this.
  8. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Glad you found multiple solutions skinwalker.
    Thanks for sharing the code for those who prefer that method. Good to know there is more than one way to skin that mammoth! :cool:
     
    skinwalker likes this.
  9. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    Yeah, it took me 2 days to figure it out and I have been trying to fix this months ago, but ended up changing the lowerface rig's parent in order to disconnect it, which causes a visible bump in the jaw, all of the other solutions available aren't working or want you to remove the lower jaw from your main character's rig, I feel like this IK fix should be the first thing that pops up, if someone searches for that solution.
     
    theANMATOR2b likes this.
  10. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    Hi,

    Can you check if your jaw is skinned correctly? If you dont need the jaw bone at all, you can just click on your character, go to configure Avatar, under Head section and make the jaw bone to be None. I think you wont be able to use the jaw on this character from other animations though (or maybe if their Avatar has the bone assigned, it will allow you - never tried that).

    Another option is to try setting the quaternion "X" to some other value, maybe serialize it in the inspector so you can change it at runtime and see what its doing.
     
  11. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    Code (CSharp):
    1.  private Animator _animator;
    2.     public Vector3 jawAngles;
    3.     // Start is called before the first frame update
    4.     void Start()
    5.     {
    6.         _animator = this.gameObject.GetComponent<Animator>();
    7.         jawAngles = _animator.GetBoneTransform(HumanBodyBones.Jaw).localEulerAngles;
    8.     }
    9.  
    10.     void LateUpdate()
    11.     {
    12.         _animator.GetBoneTransform(HumanBodyBones.Jaw).localEulerAngles = jawAngles;
    13.     }
    this should work for most characters as some are not set to all zero rotations