您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

104 行
3.8 KiB

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
namespace VRMShaders
{
public class AssetBundleCache:IDisposable
{
private Dictionary<string,AssetBundle> bundleDict=new Dictionary<string, AssetBundle>();
static AssetBundleCache instance;
public static AssetBundleCache Instance=>instance??new AssetBundleCache();
private Dictionary<string,Task<AssetBundle>>loadingDict=new Dictionary<string, Task<AssetBundle>>();
public AssetBundleCache()
{
instance=this;
}
/// <summary>
/// Set Folder Path that material bundle located
/// </summary>
/// <value></value>
public string LoadFolderPath{get;set;}
/// <summary>
/// Toggle to remove bundle hash when loading
/// </summary>
/// <value></value>
public bool IsLocal{get;set;}
public void Dispose()
{
instance=null;
foreach(var bundle in bundleDict.Values)
{
bundle.UnloadAsync(true);
}
}
public async Task<T> GetBundleAssetAsync<T>(string bundleName,string assetName)where T:UnityEngine.Object
{
AssetBundle bundle=await GetBundleAsync(bundleName);
return await bundle.GetAssetAsync<T>(assetName);
}
public async Task<AssetBundle> GetBundleAsync(string bundleName)
{
//Direct load bundle locally by using its name instead of name-hash pair
if(IsLocal)
bundleName=bundleName.Substring(0, bundleName.LastIndexOf('-'));
if(bundleDict.ContainsKey(bundleName)&&bundleDict[bundleName]!=null)
{
return bundleDict[bundleName];
}
else
{
if(loadingDict.ContainsKey(bundleName))
{
return await loadingDict[bundleName];
}
var path=Path.Combine(LoadFolderPath,bundleName);
#if UNITY_WEBGL
var request = UnityWebRequestAssetBundle.GetAssetBundle(path);
loadingDict[bundleName]= WaitAssetBundleTask(request,request.SendWebRequest());
#else
var quest=AssetBundle.LoadFromFileAsync(path);
loadingDict[bundleName]=WaitAssetBundleTask(quest);
#endif
bundleDict[bundleName]=await loadingDict[bundleName];
return bundleDict[bundleName];
}
}
private static async Task<AssetBundle> WaitAssetBundleTask(UnityWebRequest request,UnityWebRequestAsyncOperation operation)
{
while(!operation.isDone)
{
await Task.Yield();
}
return (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
}
private static async Task<AssetBundle> WaitAssetBundleTask(AssetBundleCreateRequest request)
{
while(!request.isDone)
{
await Task.Yield();
}
return request.assetBundle;
}
}
internal static class AssetBundleRequestExtension
{
internal static async Task<T> GetAssetAsync<T>(this AssetBundle bundle,string assetName) where T:UnityEngine.Object
{
var quest=bundle.LoadAssetAsync<T>(assetName);
await WaitRequestTask(quest);
return quest.asset as T;
}
private static async Task WaitRequestTask(AssetBundleRequest request)
{
while(!request.isDone)
{
await Task.Yield();
}
}
}
}