using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
namespace Chameleon.Editor.WebAssets
{
///
/// Non-blocking UnityWebRequest transport for editor tools. All requests poll on
/// EditorApplication.update — never blocks the editor. Shared by the Poly Haven
/// and ambientCG importers.
///
public static class EditorWebRequest
{
public const string UserAgent = "Chameleon-Unity-AssetImporter/1.0";
/// GET a URL and return the response body as text.
public static void GetText(string url, Action onDone, Action onError)
{
var req = UnityWebRequest.Get(url);
req.SetRequestHeader("User-Agent", UserAgent);
Send(req, () => onDone?.Invoke(req.downloadHandler.text), onError);
}
/// Fetches an image as a Texture2D (browser thumbnails, previews).
public static void GetTexture(string url, Action onDone, Action onError)
{
var req = UnityWebRequestTexture.GetTexture(url);
req.SetRequestHeader("User-Agent", UserAgent);
Send(req, () =>
{
var tex = DownloadHandlerTexture.GetContent(req);
// Survive play-mode enter/exit cleanup — otherwise Unity destroys these
// loose runtime textures and browser previews go blank.
if (tex)
tex.hideFlags = HideFlags.HideAndDontSave;
onDone?.Invoke(tex);
}, onError);
}
/// Streams a file straight to disk (no RAM peak on big downloads).
public static void DownloadFile(string url, string destPath, Action onDone,
Action onError, Action onProgress = null)
{
var req = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
req.downloadHandler = new DownloadHandlerFile(destPath) { removeFileOnAbort = true };
req.SetRequestHeader("User-Agent", UserAgent);
Send(req, () => onDone?.Invoke(), onError, onProgress);
}
public static void Send(UnityWebRequest req, Action onSuccess, Action onError,
Action onProgress = null)
{
var op = req.SendWebRequest();
void Tick()
{
if (onProgress != null && !op.isDone)
onProgress(req.downloadProgress);
if (!op.isDone)
return;
EditorApplication.update -= Tick;
try
{
if (req.result != UnityWebRequest.Result.Success)
{
onError?.Invoke($"{req.error} ({req.url})");
}
else
{
onProgress?.Invoke(1f);
onSuccess?.Invoke();
}
}
finally
{
req.Dispose();
}
}
EditorApplication.update += Tick;
}
}
}