Search Unity

Rotational animation using the blend shapes

Discussion in 'Assets and Asset Store' started by Nyanpas, May 31, 2020.

  1. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    Greetings,
    I spent a little time the day of yester looking into how to make fingers and hand rigs without using bones. I found that creating two shapekeys in Blender 3D, one for the middle, and one for the end, and lerp between them over time, was enough to help create the illusion that the fingers bend as if they were weighted to individual bones.

    The code was really easy to setup, and is here:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Shapekeying : MonoBehaviour
    6. {
    7.     public AnimationCurve CurveHalf = new AnimationCurve();
    8.     public AnimationCurve CurveFullForward = new AnimationCurve();
    9.     public AnimationCurve CurveFullBackward = new AnimationCurve();
    10.  
    11.     [Range(0f, 1f)]
    12.     public float ShapeKeyValue = 0f;
    13.  
    14.     public float Delay = 0f;
    15.     private SkinnedMeshRenderer _meshen;
    16.  
    17.     private float _timer = 0f;
    18.     private float _delayTimer = 0f;
    19.     private float _rewinder = 0f;
    20.  
    21.     private bool _playback = false;
    22.     private bool _rewind = true;
    23.     private bool _manual = false;
    24.  
    25.     // Start is called before the first frame update
    26.     void Start()
    27.     {
    28.         _meshen = GetComponentInChildren<SkinnedMeshRenderer>();
    29.         _meshen.SetBlendShapeWeight(0, 0f);
    30.         _meshen.SetBlendShapeWeight(1, 0f);
    31.     }
    32.  
    33.     // Update is called once per frame
    34.     void Update()
    35.     {
    36.         if(Input.GetKeyDown(KeyCode.X))
    37.         {
    38.             _manual = !_manual;
    39.         }
    40.  
    41.         if(_manual)
    42.         {
    43.             _meshen.SetBlendShapeWeight(0, Mathf.Abs(_rewinder - (100f * CurveFullForward.Evaluate(ShapeKeyValue))));  
    44.             _meshen.SetBlendShapeWeight(1, 100f * CurveHalf.Evaluate(ShapeKeyValue));
    45.             return;
    46.         }
    47.         else
    48.         if(!_playback && Input.GetKeyDown(KeyCode.C))
    49.         {
    50.             _rewind = !_rewind;
    51.             _rewinder = _rewind ? 100f : 0f;
    52.             _playback = true;
    53.             _timer = _delayTimer = 0f;
    54.             _meshen.SetBlendShapeWeight(0, _rewinder);
    55.             _meshen.SetBlendShapeWeight(1, 0f);
    56.         }
    57.         else
    58.         if(_playback && _delayTimer < Delay)
    59.         {
    60.             _delayTimer += Time.deltaTime;
    61.         }
    62.         else
    63.         if(_playback && _timer < 1f)
    64.         {
    65.             _timer += Time.deltaTime * 2.0f;
    66.  
    67.             _meshen.SetBlendShapeWeight(0, Mathf.Abs(_rewinder - (100f * (_rewind ? CurveFullBackward.Evaluate(_timer) : CurveFullForward.Evaluate(_timer)))));
    68.             _meshen.SetBlendShapeWeight(1, 100f * CurveHalf.Evaluate(_timer));        
    69.         }
    70.         else
    71.         {
    72.             _playback = false;
    73.         }
    74.     }
    75. }
    76.  
    The first shapekey is the one that is the start and the end, the second shapekey is the one that is only used in the middle, so it will go from 0 to 100 to 0 again, while the first goes from 0 to 100.

    In Unity I assign the scripture as it is now to the GameObject with the SkinnedMeshRenderer, and the setup is like so:
    upsetuwunity.PNG

    The result when playbacking is as follows:
    sliteimprove.gif

    Now, it's all up to you how you do the shapekeys beforehand, and also how you will use the AnimationCurves for the interpolation. There are lots of tweaks that can be done. I have used slightly modified S-curves for the blendshape that plays from start to finish, and a curve for the blendshape that is supposed to be played from start to finish and back to start again.

    I am sorry I cannot provide any help beyond this because I have extremely little time.
     
    Last edited: May 31, 2020