Search Unity

Renamed Blendshapes

Discussion in 'Animation' started by dukerustfield, Sep 18, 2020.

  1. dukerustfield

    dukerustfield

    Joined:
    Dec 5, 2019
    Posts:
    33
    I posted this under Timeline but it was recommended I post it here.

    Problem: A model has incorrect blendshape names. Let's say, "shmouth" instead of "mouth." I want to use native Unity solutions to fix this.

    Info: I'm using Timeline to animate models. I don't want to duplicate animation for incorrect blends. I know I can simply take all the curves and make them shmouths. But then that has to be done forever for everything and other people have to know that model (or others) have a shmouth. I want to stay inside Unity and not use any 3rd party apps. C# coding is fine. It's my understanding that I can't put anything on the model, codewise, to intercept the animation curves and remap because they won't ever play because the Timeline recognizes they aren't on the model.

    I'm aware it can be fixed outside Unity. I'm aware there are 3rd party products that can smush and rename/reorder skinned mesh renderers. I want to be able to put some code somewhere, anywhere, so the same animations can be used and everyone down the line doesn't have to be aware of 3rd party apps, or models that are different, or animations that are different, or I have to go back out and remodel.

    Is there a solution inside Unity?

    Sorry for the emphasis, but I think I can save people wasting their time typing solutions I don't want to use or I know of but are last resorts.

    Thanks.

    *****

    What I have currently done to "fix" it is add in the incorrect blendshape names to the same animation. Just copy the curve and change the property/path as needed. So in one file I have a curve with Mouth, the same curve with Shmouth, and the same curve with faace.Mouth. And Timeline will only play/load the appropriate shape, ignoring the others. This allows me to have one animation file for all the models, but it requires duplicating curves within those files. This isn't an ideal solution so anything better is appreciated.
     
  2. Laiken

    Laiken

    Joined:
    Nov 18, 2015
    Posts:
    50
    Not sure if you would prefer this but you could do something like this
    Code (CSharp):
    1.  
    2. public animator anim;
    3. public SkinnedMeshRenderer skin;
    4.  
    5.  
    6. public ChangeMouthBlendShape(string blendShapeGenericName, float blendShapeValue)
    7. {
    8. string blendShapeActualName;
    9. if(blendShapeGenericName == "mouth" && gameObject.name == "xxx")
    10. {
    11. blendShapeActualName = "shmouth";
    12. }
    13. else
    14. blendShapeActualName = "mouth";
    15.  
    16. int blendShapeIndex = skin.sharedMesh.GetBlendShapeIndex(blendShapeActualName);
    17. skin.SetBlendShapeWeight(blendShapeIndex, blendShapeValue);
    18. }
    19.  
    then you use the animation to activate the method, just passing the generic name for it
     
    Last edited: Sep 21, 2020
  3. dukerustfield

    dukerustfield

    Joined:
    Dec 5, 2019
    Posts:
    33
    That won't work on Timeline. You plop animation clips directly on it with links to the model. If the model doesn't have attributes that match the animation, it won't do anything. So this will never be called no matter where you put it.
     
  4. Laiken

    Laiken

    Joined:
    Nov 18, 2015
    Posts:
    50
    Sorry for the delay answering. I thought I had set to receive notification e-mails

    I forgot methods need to be triggered by animation events, so it would not be possible easily animate that way. Maybe animations can change properties and you could use them to trigger the methods (not 100% sure if possible), but I think I figured out a better way:

    It seems you can actually change the blendshape names directly on Unity. I didn't test yet but it should work.

    use this to get the blendshape data:
    https://docs.unity3d.com/ScriptReference/Mesh.GetBlendShapeFrameVertices.html

    use this to make a copy of that blendshape data on the mesh, but with the name you want
    https://docs.unity3d.com/ScriptReference/Mesh.AddBlendShapeFrame.html
     
    Last edited: Sep 28, 2020