Coroutines that change value by reference

IEnumerator ChangeFloatBetween( float duration, float from, float to, Action callback, Action post )
{
    float value;
    var elapsedTime = 0f;
    while ( elapsedTime < duration )
    {
        elapsedTime += Time.deltaTime;
        value = Mathf.Lerp( from, to, elapsedTime / duration );
        yield return new WaitForEndOfFrame();
        callback( value );
    }
    value = to;
    callback( value );
    if ( post != null )
    {
        post();
    }
}

IEnumerator ChangeFloatBetween( float duration, float from, float to, Action callback )
{
    yield return ChangeFloatBetween( duration, from, to, callback, null );
}

This method can be used to change values of an image’s alpha for example, like this:

public void FadeIn( float duration = 3f )
{
   const float @from = 0f;
   const float to = 1f;
   foreach ( var material in MeshRenderer.materials )
   {
      var materialCopy = material;
      StartCoroutine( 
         ChangeFloatBetween( duration, from, to, ( alpha ) =>
            {
               materialCopy.color = new Color( 
                  materialCopy.color.r, 
                  materialCopy.color.g, 
                  materialCopy.color.b,
                  alpha );
            }) );
   }
}

– – –

We might want to do something after the increment is finished.
Like we do here, when we want to animate health UI after you drink a potion:

public void IncrementHP( float duration, int currentHP, int hpIncrement, Text hpText )
{
    StartCoroutine(
        ChangeFloatBetween( duration, currentHP, currentHP + hpIncrement, ( risingHP ) =>
        {
            hpText.text = Math.Ceiling( risingHP );
        }, () =>
        {
            Debug.Log("Finished incrementing HP");
        } ) );
}

– – –

We can also of course use this to change the position or rotation of a game object, example:

public void MoveThing( GameObject thing, float duration, float xMovementStep)
{
   var initialX = thing.transform.position.x;
    StartCoroutine(
        ChangeFloatBetween( duration, initialX , initialX + movementStep, ( risingX ) =>
        {
            thing.transform.SetX(movementStep);
        } ) );
}

In this example we’re using the SetX extension method, that I’ve covered that in my ‘Transform Extension Methods’ post.

Leave a Reply

Your email address will not be published. Required fields are marked *