Game.UnityWebRequestExtensionMethods
Assembly: Assembly-CSharp
Namespace: Game
Type: static class
Base: System.Object
Summary: Extension helpers that implement the C# awaiter pattern for UnityEngine.Networking.UnityWebRequestAsyncOperation. Provides a nested awaiter (UnityWebRequestAwaiter) that subscribes to the async operation's completion event and implements INotifyCompletion so UnityWebRequestAsyncOperation instances can be awaited directly. Also adds ConfigureAwait to integrate UnityWebRequest polling with the game's updater loop, supporting cancellation tokens and a simple "stalled connection" timeout. This utility is intended for Cities: Skylines 2 modding where you want to await UnityWebRequest operations while integrating with the game's update system (GameManager.instance.RegisterUpdater).
Fields
-
private UnityEngine.Networking.UnityWebRequestAsyncOperation asyncOp
Holds the UnityWebRequestAsyncOperation being awaited. Subscribed to asyncOp.completed in the awaiter constructor so the awaiter is notified when the operation finishes. -
private System.Action continuation
Stores the continuation delegate passed to OnCompleted. Invoked when the async operation completes (via the completed event or if the operation is already done when OnCompleted is called).
Properties
public bool IsCompleted { get; }
Returns whether the wrapped UnityWebRequestAsyncOperation has finished (returns asyncOp.isDone). Used by the awaiter pattern to decide if the await should yield.
Constructors
public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
Creates a new awaiter for the supplied UnityWebRequestAsyncOperation. Subscribes to asyncOp.completed so OnRequestCompleted is called when the operation completes. Use this through the provided GetAwaiter extension methods rather than instantiating directly.
Methods
-
public UnityWebRequest.Result GetResult()
Called by the await pattern after completion. Returns the UnityWebRequest.Result (success, error states) from asyncOp.webRequest.result. -
public void OnCompleted(Action continuation)
Stores the continuation and, if the operation is already completed, invokes OnRequestCompleted immediately to run the continuation. This satisfies the INotifyCompletion contract. -
public void OnRequestCompleted(AsyncOperation obj)
Handler for the asyncOp.completed event. Invokes the stored continuation if present. -
public UnityWebRequestAwaiter GetAwaiter()
Instance method that returns this; part of the awaiter implementation allowing the awaiter itself to be used directly. -
public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
Extension method so you can writeawait someUnityWebRequest.SendWebRequest();
. Creates a UnityWebRequestAwaiter, which subscribes to the completion event and implements the await pattern. -
public static UnityWebRequestAwaiter ConfigureAwait(this UnityWebRequestAsyncOperation asyncOperation, Func<UnityWebRequestAsyncOperation, bool> updaterMethod, CancellationToken token, float connectionTimeout = 0f)
Registers a per-frame updater with GameManager.instance.RegisterUpdater to monitor the operation. The updaterMethod should return true when the updater is finished (so it gets unregistered). This method also: - Aborts the web request if the CancellationToken is cancelled.
- Optionally enforces a connection timeout: if progress stalls for longer than connectionTimeout seconds, the request is aborted. Returns a UnityWebRequestAwaiter for awaiting the operation. This method integrates web requests with the game's update loop and provides cancellation/timeouts not available directly from Unity's async operation.
Usage Example
using System;
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;
using Game; // namespace containing the extensions
public class Example
{
public async void DownloadExample()
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); // overall cancellation
var request = UnityWebRequest.Get("https://example.com/data.json");
var op = request.SendWebRequest();
// Simple updater that unregisters when the operation is done.
Func<UnityWebRequestAsyncOperation, bool> updater = (asyncOp) =>
{
// return true to unregister the updater; keep returning false to continue.
return asyncOp.isDone;
};
// Await the request while integrating with the game's updater loop.
UnityWebRequest.Result result = await op.ConfigureAwait(updater, cts.Token, connectionTimeout: 10f);
if (result == UnityWebRequest.Result.Success)
{
string text = request.downloadHandler.text;
Debug.Log("Downloaded: " + text);
}
else
{
Debug.LogWarning($"Request failed: {request.result}");
}
}
}
Additional notes: - ConfigureAwait relies on GameManager.instance.RegisterUpdater being present and functioning in the mod environment. - If cancellation is requested or the connection times out (based on stalled progress), the underlying webRequest is aborted which will cause the operation to complete with an error result.