using System;
using System.Collections;
using System.IO;
using TriLibCore.General;
using TriLibCore.Utils;
using UnityEngine;
using UnityEngine.Networking;
namespace TriLibCore
{
/// Represents a class used to download Models with Coroutines used by the Asset Downloader.
public class AssetDownloaderBehaviour : MonoBehaviour
{
///
/// Unity web request instance used on this script.
///
private UnityWebRequest _unityWebRequest;
///
/// Method to call when the model downloading progress changes.
///
private Action _onProgress;
///
/// Context used to load the model.
///
private AssetLoaderContext _assetLoaderContext;
/// Downloads the Model using the given Request and options.
/// The Unity Web Request used to load the Model. You can use the CreateWebRequest method to create a new Unity Web Request or pass your instance.
/// The Method to call on the Main Thread when the Model is loaded but resources may still pending.
/// The Method to call on the Main Thread when the Model and resources are loaded.
/// The Method to call when the Model loading progress changes.
/// The Game Object that will be the parent of the loaded Game Object. Can be null.
/// The Method to call on the Main Thread when any error occurs.
/// The options to use when loading the Model.
/// The Custom Data that will be passed along the Context.
/// The extension of the URI Model.
/// Pass true if your file is a Zip file.
/// The download coroutine enumerator.
public IEnumerator DownloadAsset(UnityWebRequest unityWebRequest, Action onLoad, Action onMaterialsLoad, Action onProgress, GameObject wrapperGameObject, Action onError, AssetLoaderOptions assetLoaderOptions, object customContextData, string fileExtension, bool? isZipFile = null)
{
_unityWebRequest = unityWebRequest;
_onProgress = onProgress;
yield return unityWebRequest.SendWebRequest();
try
{
if (unityWebRequest.responseCode < 400)
{
var memoryStream = new MemoryStream(_unityWebRequest.downloadHandler.data);
var customDataDic = (object)CustomDataHelper.CreateCustomDataDictionaryWithData(new UriLoadCustomContextData
{
UnityWebRequest = _unityWebRequest
});
if (customContextData != null)
{
CustomDataHelper.SetCustomData(ref customDataDic, customContextData);
}
var contentType = unityWebRequest.GetResponseHeader("Content-Type");
if (contentType != null && isZipFile == null)
{
isZipFile = contentType.Contains("application/zip") || contentType.Contains("application/x-zip-compressed") || contentType.Contains("multipart/x-zip");
}
if (!isZipFile.GetValueOrDefault() && string.IsNullOrWhiteSpace(fileExtension))
{
fileExtension = FileUtils.GetFileExtension(unityWebRequest.url);
}
if (isZipFile.GetValueOrDefault())
{
_assetLoaderContext = AssetLoaderZip.LoadModelFromZipStream(memoryStream, onLoad, onMaterialsLoad, delegate (AssetLoaderContext assetLoaderContext, float progress) { onProgress?.Invoke(assetLoaderContext, 0.5f + progress * 0.5f); }, onError, wrapperGameObject, assetLoaderOptions, customDataDic, fileExtension);
}
else
{
_assetLoaderContext = AssetLoader.LoadModelFromStream(memoryStream, null, fileExtension, onLoad, onMaterialsLoad, delegate (AssetLoaderContext assetLoaderContext, float progress) { onProgress?.Invoke(assetLoaderContext, 0.5f + progress * 0.5f); }, onError, wrapperGameObject, assetLoaderOptions, customDataDic);
}
}
else
{
var exception = new Exception($"UnityWebRequest error:{unityWebRequest.error}, code:{unityWebRequest.responseCode}");
throw exception;
}
}
catch (Exception exception)
{
if (onError != null)
{
var contextualizedError = exception as IContextualizedError;
onError(contextualizedError ?? new ContextualizedError(exception, null));
}
else
{
throw;
}
}
Destroy(gameObject);
}
/// Updates the download progress.
private void Update()
{
_onProgress?.Invoke(_assetLoaderContext, _unityWebRequest.downloadProgress * 0.5F);
}
}
}