您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
104 行
3.8 KiB
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|