0
\$\begingroup\$

I am trying create a small lerp helper script that basically allows me to do something like a small tween with a extension or static method (So I can call it from my other scripts easily like you can do with tween libraries). I know how to do a simple lerp for this with an corutin or in Update, but I don't understand how to make it work with extension or static methods because I can't really use corutines or update there.

EDIT:

With the help of answer bellow I ended Up solving this with async await. Which I can confirm worked in WebGl in this example (I think that is because I didn't run it on a new thread) Here is my code:

    public static async void LerpPositionXAsync(this Transform target, float endPosition, float duration)
    {
        float elapsedTime = 0;
        float startPossitionX = target.localPosition.x;

        while (elapsedTime < duration)
        {
            elapsedTime += Time.deltaTime;
            target.localPosition = new Vector3(Mathf.Lerp(startPossitionX, endPosition, elapsedTime / duration),
                target.localPosition.y);

            await Task.Yield();
        }

        //Makes sure possition is correct after animation
        target.localPosition = new Vector3(endPosition,
                target.localPosition.y); 

        await Task.Yield();
    }

Note that I am lerping a float value here and not Vector3 but it works the same.

UPDATE

Since I posted this question I have learned that Task.Delay() specifically doesn't work with WebGl so you you should probably be fine if you don't use that or you don't start any tasks. However in Unity 2023 (Not sure for the older ones) they added Awaitable class for the async workflow that works similar to the coroutine and it is supported by WebGl so if you are thinking about using async with WebGl I would recommend that.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Two options:

  1. You can pass in a Monobehaviour to the static / extension to perform the coroutine or update. Something similar to a functionTimer that CodeMonkey makes in this video. Except his way is to instantiate a monobehavior gameObject, where as in your case, you can inject in by the caller when caller is a monobehaviour.

  2. You can use async/awaits that is from c#. Or better yet use Unitask which is async/await integration for Unity.

Addition Note

If you are targeting WebGL build, async and Unitask is not supported. So you will be stuck with using coroutine. I later thought of the way of not having to inject monobehaviour in it since the caller is usually a MonoBehaviour, so your extension just have to be an IEnumerator. Here's an example code on how it could be done:

using UnityEngine;

public static class LerpHelper
{
    public static IEnumerator LerpPosition(this Transform transform, Vector3 targetPosition, float duration)
    {
        float elapsedTime = 0f;
        Vector3 startPosition = transform.position;

        while (elapsedTime < duration)
        {
            elapsedTime += Time.deltaTime;
            float t = Mathf.Clamp01(elapsedTime / duration);
            transform.position = Vector3.Lerp(startPosition, targetPosition, t);
            yield return null;
        }

        transform.position = targetPosition;
    }
}
 

public class ExampleCaller : MonoBehaviour
{
    [SerializeField] private Transform targetTransform;
    [SerializeField] private Vector3 targetPosition;
    [SerializeField] private float duration = 1f;

    private void Start()
    {
        // Example usage of the LerpPosition extension method
        StartCoroutine(targetTransform.LerpPosition(targetPosition, duration));
    }
}
\$\endgroup\$
5
  • \$\begingroup\$ If I go for an async/await option would that work also on WebGl? I remember reading something about it not working there but I am not sure. \$\endgroup\$
    – Ivan
    Commented Jun 23, 2023 at 7:04
  • \$\begingroup\$ Unfortunately no, WebGL build dont support async nor Unitask. You are left with using Unity Coroutine if you are targeting WebGL. \$\endgroup\$ Commented Jun 23, 2023 at 7:57
  • \$\begingroup\$ Ok did a little more research and it seams I can use async/await in WebGl as long as it doesn't involves more than on thread. I will do some experiments and cheek it out. \$\endgroup\$
    – Ivan
    Commented Jun 23, 2023 at 9:07
  • \$\begingroup\$ cool, good to know~ \$\endgroup\$ Commented Jun 23, 2023 at 9:37
  • \$\begingroup\$ I can confirm it works in WebGl \$\endgroup\$
    – Ivan
    Commented Jun 23, 2023 at 11:30

You must log in to answer this question.

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