Search Unity

Character stays with mouth open

Discussion in 'Editor & General Support' started by Larpushka, Oct 20, 2015.

Thread Status:
Not open for further replies.
  1. Larpushka

    Larpushka

    Joined:
    Jan 6, 2015
    Posts:
    214
    So I created a character with makehuman, gave it a "game rig", defined it as humanoid and configured it with mecanim. It was mapped without errors. I added animation to it ("idle animation" on asset store), the animation plays correctly but the mouth stays open all the time! How come? The animation has nothing to do with the mouth. If I remove the animation the character doesn't open its mouth when I click "play".

    And by the way, if I go to the "muscles" tab in mecanim I see the character in a pretty weird body position (when I'll get home I'll take a screenshot). I played around with the muscles until I got the character to be in a regular position but still, once I click play and the animation plays, the mouth stays open all the time.
     
  2. clarice_hilton

    clarice_hilton

    Joined:
    Jun 29, 2016
    Posts:
    1
    Did you find a solution for this? I'm experiencing the same issue now for all animations.
     
  3. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    306
    This is a problem where the animation was maped differently, to work around it when you rig your character go to Head, there try to find the right bone for the Jaw, or if you dont care abouth mouth animation you can just delete the mapping for the Jaw
     
    Last edited: Jul 31, 2016
    heartingNinja likes this.
  4. jorgeolothar

    jorgeolothar

    Joined:
    Mar 27, 2016
    Posts:
    26
    I had no mapping for the jaw, but once I mapped it to HeadEnd as suggested in this post, the character kept it s mouth shut.
     
  5. Tsilliev

    Tsilliev

    Joined:
    Jan 21, 2014
    Posts:
    35
    I confirm, I click on the mdm3male avatar, I click configure, I go to head, and at the jaw field I will select None, saving fixed the problem.
     
  6. MichaelClaridge

    MichaelClaridge

    Joined:
    Mar 26, 2017
    Posts:
    1
    Thank you! Spot on! I did try setting the jaw muscles, but that didn't seem to make any difference.
     
  7. kInG_jUlLian_85

    kInG_jUlLian_85

    Joined:
    Dec 7, 2012
    Posts:
    5
    You saved my life. It fixed for me @Tsilliev . Before this I tried almost everything in the universe but didn't work. Thanks a lot.
     
  8. fredcox

    fredcox

    Joined:
    Mar 24, 2021
    Posts:
    1
    The big problem in delete jaw bone is if you want using mouth animation after. This is one failure in unity, because one problem without any solution.
     
  9. Then you reimport the original with the jawbone. It's not exactly rocket-science.
     
  10. Wreckertike

    Wreckertike

    Joined:
    Feb 6, 2014
    Posts:
    7
    lifesavers!
     
  11. shma_unity

    shma_unity

    Joined:
    Jun 13, 2018
    Posts:
    118
    I wrote a fix utility for Animations that don't have a Jawbone.
    It will set the keyframes of the Jawbone to a specific value (1 by default) to put the jaw in a default position.
    To install, copy the script into an "Editor" folder in your Assets of your project. If none exist, you can create one and name it Editor (so that the script doesn't get compiled on build, because it uses editor functionality.)
    Open it via Window->Fix Jawbone Keyframes
    Then you can just drag&drop the AnimationClips that have the open mouth problem into the box and hit the button. Done.

    (If the animations are in an FBX, duplicate them so they become editable (ctrl+d).)

    Code (CSharp):
    1. //Copyright(c) 2021 Robin Promesberger (schema_unity on forum.unity3d.com)
    2. //
    3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
    4. // software and associated documentation files (the "Software"), to deal in the Software without
    5. // restriction, including without limitation the rights to use, copy, modify, merge, publish,
    6. // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
    7. // Software is furnished to do so, subject to
    8. // the following conditions:
    9. // The above copyright notice and this permission notice shall be included in all copies or
    10. // substantial portions of the Software.
    11. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    12. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    13. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    14. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    15. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    16. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
    17. // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    18. // SOFTWARE.
    19. using UnityEngine;
    20. using UnityEditor;
    21. using System.Collections.Generic;
    22. using System.Linq;
    23.  
    24. public class FixJawBoneKeyframes : EditorWindow
    25. {
    26.     [MenuItem("Window/Fix Jawbone Keyframes")]
    27.     public static void OpenWindow()
    28.     {
    29.         var window = GetWindow<FixJawBoneKeyframes>();
    30.         window.titleContent = new GUIContent("Jaw Fixer");
    31.     }
    32.     private GUIContent statusContent = new GUIContent("Waiting...");
    33.     public List<AnimationClip> animations = new List<AnimationClip>();
    34.     private Transform rootBone;
    35.     Vector2 scrollPos;
    36.     private float keyValue = 1;
    37.     private string bindingName = "Jaw Close";
    38.     private string statusText = "Waiting...";
    39.     private void OnGUI()
    40.     {
    41.         keyValue = EditorGUILayout.FloatField("Jaw Keyframe val", keyValue);
    42.  
    43.         GUIStyle GuistyleBoxDND = new GUIStyle(GUI.skin.box);
    44.         Rect myRect = GUILayoutUtility.GetRect(0, 40, GUILayout.ExpandWidth(true));
    45.         GUI.Box(myRect, "Drag and Drop AnimationClips to this Box!", GuistyleBoxDND);
    46.         //drag and drop box
    47.         if (myRect.Contains(Event.current.mousePosition))
    48.         {
    49.             if (Event.current.type == EventType.DragUpdated)
    50.             {
    51.                 DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
    52.                 Event.current.Use();
    53.             }
    54.             else if (Event.current.type == EventType.DragPerform)
    55.             {
    56.                 Debug.Log(DragAndDrop.objectReferences.Length);
    57.                 for (int i = 0; i < DragAndDrop.objectReferences.Length; i++)
    58.                 {
    59.                     if(DragAndDrop.objectReferences[i] is AnimationClip)
    60.                     {
    61.                         animations.Add(DragAndDrop.objectReferences[i] as AnimationClip);
    62.                     }
    63.                 }
    64.                 Event.current.Use();
    65.             }
    66.         }
    67.         EditorGUILayout.BeginHorizontal();
    68.         scrollPos =
    69.             EditorGUILayout.BeginScrollView(scrollPos, true, true);
    70.      
    71.         //list of animation clips
    72.         var list = animations;
    73.         int newCount = Mathf.Max(0, EditorGUILayout.DelayedIntField("size", list.Count));
    74.         while (newCount < list.Count)
    75.             list.RemoveAt(list.Count - 1);
    76.         while (newCount > list.Count)
    77.             list.Add(null);
    78.  
    79.         for (int i = 0; i < list.Count; i++)
    80.         {
    81.             list[i] = EditorGUILayout.ObjectField(list[i], typeof(AnimationClip), true) as AnimationClip;
    82.         }
    83.  
    84.  
    85.         EditorGUILayout.EndScrollView();
    86.  
    87.         EditorGUILayout.EndHorizontal();
    88.  
    89.  
    90.         bool enabled = (list != null && list.Count > 0);
    91.         if (!enabled)
    92.         {
    93.             statusText = "Add animation clips to process.";
    94.         }
    95.         GUI.enabled = enabled;
    96.         //processing
    97.         if (GUILayout.Button("Fix Jaw Bones"))
    98.         {
    99.             statusText = "++ Processing animations... ++\n\n";
    100.             // process clips
    101.             foreach(AnimationClip clip in list)
    102.             {
    103.  
    104.                 EditorCurveBinding[] binding = AnimationUtility.GetCurveBindings(clip);
    105.                 bool found = false; ;
    106.                 //we could reference the name directly, but since performance is not an issue, it's more convenient and safer to use the existing binding
    107.                 for (int i = 0; i < binding.Length; i++)
    108.                 {
    109.                     if (binding[i].propertyName == bindingName)
    110.                     {
    111.                         found = true;
    112.  
    113.                         AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding[i]);
    114.                         //set each existing keyframe to the value provided (by default unity creates one at the start and end)
    115.                         Keyframe[] copy = curve.keys; //this creates a copy of the array
    116.                         for (int k = 0; k < copy.Length; k++)
    117.                         {
    118.                             copy[k].value = keyValue;
    119.                         }
    120.                         curve.keys = copy; //this copies the array into the curve
    121.                         statusText += "Processed keyframes of " + clip.name+"\n";
    122.                         //set the curve for the binding
    123.                         AnimationUtility.SetEditorCurve(clip, binding[i], curve);
    124.                         break;
    125.                     }
    126.                 }
    127.                 if (!found)
    128.                 {
    129.                     statusText += "ERROR: '"+ bindingName+"' binding not found. Animation has to be humanoid\n";
    130.                     break;
    131.                 }
    132.             }
    133.         }
    134.         // Draw status info
    135.         statusContent.text = statusText;
    136.         EditorStyles.label.wordWrap = true;
    137.  
    138.         EditorGUILayout.BeginHorizontal();
    139.         scrollPos =
    140.             EditorGUILayout.BeginScrollView(scrollPos, true, true);
    141.         GUILayout.Label(statusContent);
    142.         EditorGUILayout.EndScrollView();
    143.  
    144.         EditorGUILayout.EndHorizontal();
    145.  
    146.     }
    147. }
     
  12. QuarterMillion

    QuarterMillion

    Joined:
    Jul 18, 2020
    Posts:
    10
    Running into same issue with makehuman model.

    Or you could have two versions of the same model have one with jaw bone as a stand in for the one actually used in the game in those cut scenes when its used.

    Unless you're going for something along the lines of the incredible headset lip syncage of GTA V where a player's rigged avatar moves its lips when a player talks through their headset in real time in game... Yeah there really should be a fix for this.

    Side note @schema_unity : if you aren't using the editor any more and built the game as a standalone will the Editor folder files you create still work since technically you're no longer using the Unity Editor?

    Likewise does coding with the using UnityEditor still work outside the editor in a standalone build scenario?
     
  13. Lay84

    Lay84

    Joined:
    Mar 8, 2014
    Posts:
    34
    Very helpful, Thank you!!!!
     
  14. GXMark

    GXMark

    Joined:
    Oct 13, 2012
    Posts:
    515
    There is nothing in this code that determines the jaw bone. Also how does it update the clip in the project view. I don't see any save unless its just be default.
     
  15. shma_unity

    shma_unity

    Joined:
    Jun 13, 2018
    Posts:
    118
    Mecanim Rigs contain bindings for controlling multiple bones. One of them is "Jaw Close". To look at it you can create a new animation for a Mecanim rig and create a new property to see all of them.

    The problem of the open jaw is that most preset animation clips that weren't originally made for this rig don't have an animation for this property, so it defaults to 0. The script defaults it to 1.

    Accessing AnimationClips like this is accessing the asset, not a clone of it, so any changes are done to the asset.
     
    GXMark likes this.
  16. the_Whizzkid

    the_Whizzkid

    Joined:
    Apr 15, 2020
    Posts:
    20
     
Thread Status:
Not open for further replies.