Skip to main content
deleted 3 characters in body
Source Link
Evorlor
  • 5.9k
  • 9
  • 59
  • 101

It is slightly hacky. Using cancellation tokens as commented by @DMGregory is probably the better way to go. But I have been using this method for a few years without issue. (But I think I'llI will probably dehackify it, and update this answer when I do.)

It is slightly hacky. Using cancellation tokens as commented by @DMGregory is probably the better way to go. But I have been using this method for a few years without issue. (But I think I'll will probably dehackify it, and update this answer when I do.)

It is slightly hacky. Using cancellation tokens as commented by @DMGregory is probably the better way to go. But I have been using this method for a few years without issue. (But I think I will probably dehackify it, and update this answer when I do.)

Source Link
Evorlor
  • 5.9k
  • 9
  • 59
  • 101

I use a utility class for my async/await conditionals. I have slightly modified it for your use case (untested):

public static class TaskUtility
{
    private static readonly int DeltaTime;

    static TaskUtility()
    {
        DeltaTime = 1000 / MainCamera.instance.MaxFrameRate;
    }

    /// <summary>
    /// Whiles while the function is true
    /// </summary>
    /// <param name="condition">The function to check</param>
    public static async Task WaitWhile(Func<bool> condition)
    {
        while (condition() && Application.isPlaying)
        {
            await Task.Delay(DeltaTime);
        }
    }

    /// <summary>
    /// Waits until the function is true
    /// </summary>
    /// <param name="condition">The function to wait on</param>
    public static async Task WaitUntil(Func<bool> condition)
    {
        while (!condition() && Application.isPlaying)
        {
            await Task.Delay(DeltaTime);
        }
    }
}

Which would change your code to:

public static async Task<Texture2D> DownloadTexture(string uri)
{
    using (
        UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(uri, true)
    )
    {
        var asyncOp = uwr.SendWebRequest();

        if (WeatherTracker.instance == null)
        {
            uwr.Abort(); // todo: something related to this is crashing the editor while textures are still being download @jkr
            return null;
        }

        await TaskUtility.WaitUntil(() => asyncOp.isDone);

        // return this.uwr.SendWebRequest();
        // Debug.Log($"download tex {z}/{x}/{y}");
        if (uwr.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"{uwr.error}: {uri}");
            return null;
        }
        else
        {
            return DownloadHandlerTexture.GetContent(uwr);
        }
    }
}

This should effectively do the same thing as your code, except it pretends the condition is complete (which is a lie) if you press stop in the editor. (Note: It may behave differently on build.)

It is slightly hacky. Using cancellation tokens as commented by @DMGregory is probably the better way to go. But I have been using this method for a few years without issue. (But I think I'll will probably dehackify it, and update this answer when I do.)