using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BlendShapesController : MonoBehaviour
    private SkinnedMeshRenderer bodySkinnedMeshRenderer;
    private bool randomizeNumbers = true;

    // Start is called before the first frame update
    void Start()
        bodySkinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();

    // Update is called once per frame
    void Update()
        if(randomizeNumbers == true)

            randomizeNumbers = false;

    IEnumerator RandomNumbers()
        int rand = Random.Range(0, 23);
        bodySkinnedMeshRenderer.SetBlendShapeWeight(0, rand);

        yield return new WaitForSeconds(0.3f);

        randomizeNumbers = true;

Now I'm using a random number betwen 0 and 23 every 0.3f seconds. I want to change it so it will lerp in the SetBlendShapeWeight at index 0 but instead rand it will lerp from 0 to 23 then from 23 to 0 when done stop waiting seconds.

So the time or speed should be set for the lerp and according to that how much time to wait. For example if the lerp will take 5 seconds from 0 to 23 and then back from 23 to 0 then after 5 seconds start the Coroutine again.

The idea is to make some kind of mouth talk fake/cheat. So I want to mouth to be open/close smooth between 0 and 23 and then 23 to 0 before starting the new Coroutine and to be able to decide how much time it will take to make the lerp from 0 to 23 and 23 to 0.

In the screenshot when the blendshape of the mouth is set to 0 the mouth is open at 23 or 27 the mouth is closed. So I want to simulate mouth talking between this range of numbers for example each 0.3f make the mouth close/open then after 0.3f again mouth close/open and so on.

Blendshape of the mouth_closed

  • \$\begingroup\$ I am trying to follow your question but I can't quite understand what you're asking. Can you try to edit your question with a clearer explanation of what you want to accomplish? \$\endgroup\$
    – Kevin
    Aug 22, 2020 at 18:27
  • \$\begingroup\$ @Kevin In this line bodySkinnedMeshRenderer.SetBlendShapeWeight(0, rand); instead using rand I want to make something like while or something that will lerp between 0 to 23 when it's getting to 23 to lerp back to 0 all that should take X seconds when it finish lerping forth and back then to start the Coroutine over again. For example each 0.5f seconds the mouth will be closed and open after 0.5f again the mouth will be close and open by lerping the value in the SetBlendShapeWeight it will close and open the mouth. \$\endgroup\$ Aug 22, 2020 at 18:38
  • \$\begingroup\$ @Kevin The main goal is to change the blendshape value in the SetBlendShapeWeight to simulate mouth talking. \$\endgroup\$ Aug 22, 2020 at 18:41

1 Answer 1

//Lerp between startValue and endValue over 'duration' seconds
private IEnumerator LerpShape(float startValue, float endValue, float duration) {
    float elapsed = 0;
    while (elapsed  < duration) {
        elapsed += Time.deltaTime;
        float value = Mathf.Lerp(startValue, endValue, elapsed / duration);
        bodySkinnedMeshRenderer.SetBlendShapeWeight(0, value);
        yield return null;

private bool talking = true;
//animate open and closed, then repeat
private IEnumerator AnimateMouth() {
    while (talking) {
        //yield return StartCoroutine waits for that coroutine to finish before continuing
        yield return StartCoroutine(LerpShape(0, 23, .5f));
        yield return StartCoroutine(LerpShape(23, 0, .5f));


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .