| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading.Tasks;
- using UnityEngine;
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
- namespace Model
- {
- public class ABInfo: Disposer
- {
- private int refCount;
- public string Name { get; }
- public int RefCount
- {
- get
- {
- return this.refCount;
- }
- set
- {
- Log.Debug($"{this.Name} refcount: {value}");
- this.refCount = value;
- }
- }
- public AssetBundle AssetBundle { get; }
- public ABInfo(string name, AssetBundle ab)
- {
- this.Name = name;
- this.AssetBundle = ab;
- this.RefCount = 1;
- Log.Debug($"load assetbundle: {this.Name}");
- }
- public override void Dispose()
- {
- if (this.Id == 0)
- {
- return;
- }
-
- base.Dispose();
-
- Log.Debug($"desdroy assetbundle: {this.Name}");
-
- this.AssetBundle?.Unload(true);
- }
- }
- public class ResourcesComponent : Component
- {
- public static AssetBundleManifest AssetBundleManifestObject { get; set; }
- private readonly Dictionary<string, UnityEngine.Object> resourceCache = new Dictionary<string, UnityEngine.Object>();
- private readonly Dictionary<string, ABInfo> bundles = new Dictionary<string, ABInfo>();
-
- // lru缓存队列
- private readonly QueueDictionary<string, ABInfo> cacheDictionary = new QueueDictionary<string, ABInfo>();
- public K GetAsset<K>(string bundleName, string prefab) where K : class
- {
- string path = $"{bundleName}.unity3d/{prefab}".ToLower();
- UnityEngine.Object resource = null;
- if (!this.resourceCache.TryGetValue(path, out resource))
- {
- throw new Exception($"not found asset: {path}");
- }
-
- return resource as K;
- }
- public void UnloadBundle(string assetBundleName)
- {
- assetBundleName = assetBundleName.ToLower();
-
- this.UnloadOneBundle(assetBundleName);
- string[] dependencies = ResourcesHelper.GetDependencies(assetBundleName);
- //Log.Debug($"-----------dep unload {assetBundleName} dep: {dependencies.ToList().ListToString()}");
- foreach (string dependency in dependencies)
- {
- this.UnloadOneBundle(dependency);
- }
- }
- private void UnloadOneBundle(string assetBundleName)
- {
- assetBundleName = assetBundleName.ToLower();
-
- //Log.Debug($"unload bundle {assetBundleName}");
- ABInfo abInfo;
- if (!this.bundles.TryGetValue(assetBundleName, out abInfo))
- {
- throw new Exception($"not found assetBundle: {assetBundleName}");
- }
- --abInfo.RefCount;
- if (abInfo.RefCount > 0)
- {
- return;
- }
-
-
- this.bundles.Remove(assetBundleName);
-
- // 缓存10个包
- this.cacheDictionary.Enqueue(assetBundleName, abInfo);
- if (this.cacheDictionary.Count > 10)
- {
- abInfo = this.cacheDictionary[this.cacheDictionary.FirstKey];
- this.cacheDictionary.Dequeue();
- abInfo.Dispose();
- }
- Log.Debug($"cache count: {this.cacheDictionary.Count}");
- }
-
- /// <summary>
- /// 同步加载assetbundle
- /// </summary>
- /// <param name="assetBundleName"></param>
- /// <returns></returns>
- public void LoadBundle(string assetBundleName)
- {
- assetBundleName = assetBundleName.ToLower();
- this.LoadOneBundle(assetBundleName);
- string[] dependencies = ResourcesHelper.GetDependencies(assetBundleName);
- Log.Debug($"-----------dep load {assetBundleName} dep: {dependencies.ToList().ListToString()}");
- foreach (string dependency in dependencies)
- {
- if (string.IsNullOrEmpty(dependency))
- {
- continue;
- }
- this.LoadOneBundle(dependency);
- }
- }
-
- public void LoadOneBundle(string assetBundleName)
- {
- ABInfo abInfo;
- if (this.bundles.TryGetValue(assetBundleName, out abInfo))
- {
- ++abInfo.RefCount;
- return;
- }
- if (this.cacheDictionary.ContainsKey(assetBundleName))
- {
- abInfo = this.cacheDictionary[assetBundleName];
- ++abInfo.RefCount;
- this.bundles[assetBundleName] = abInfo;
- this.cacheDictionary.Remove(assetBundleName);
- return;
- }
-
- if (!Define.IsAsync)
- {
- #if UNITY_EDITOR
- string[] realPath = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
- foreach (string s in realPath)
- {
- string assetName = Path.GetFileNameWithoutExtension(s);
- string path = $"{assetBundleName}/{assetName}".ToLower();
- UnityEngine.Object resource = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(s);
- this.resourceCache[path] = resource;
- }
-
- this.bundles[assetBundleName] = new ABInfo(assetBundleName, null);
- return;
- #endif
- }
- AssetBundle assetBundle = AssetBundle.LoadFromFile(Path.Combine(PathHelper.AppResPath, assetBundleName));
- if (!assetBundle.isStreamedSceneAssetBundle)
- {
- // 异步load资源到内存cache住
- UnityEngine.Object[] assets = assetBundle.LoadAllAssets();
- foreach (UnityEngine.Object asset in assets)
- {
- string path = $"{assetBundleName}/{asset.name}".ToLower();
- this.resourceCache[path] = asset;
- }
- }
-
- this.bundles[assetBundleName] = new ABInfo(assetBundleName, assetBundle);
- }
- /// <summary>
- /// 异步加载assetbundle
- /// </summary>
- /// <param name="assetBundleName"></param>
- /// <returns></returns>
- public async Task LoadBundleAsync(string assetBundleName)
- {
- assetBundleName = assetBundleName.ToLower();
- await this.LoadOneBundleAsync(assetBundleName);
- string[] dependencies = ResourcesHelper.GetDependencies(assetBundleName);
- //Log.Debug($"-----------dep load {assetBundleName} dep: {dependencies.ToList().ListToString()}");
- foreach (string dependency in dependencies)
- {
- if (string.IsNullOrEmpty(dependency))
- {
- continue;
- }
- await this.LoadOneBundleAsync(dependency);
- }
- }
- public async Task LoadOneBundleAsync(string assetBundleName)
- {
- ABInfo abInfo;
- if (this.bundles.TryGetValue(assetBundleName, out abInfo))
- {
- ++abInfo.RefCount;
- return;
- }
- if (this.cacheDictionary.ContainsKey(assetBundleName))
- {
- abInfo = this.cacheDictionary[assetBundleName];
- ++abInfo.RefCount;
- this.bundles[assetBundleName] = abInfo;
- this.cacheDictionary.Remove(assetBundleName);
- return;
- }
-
- if (!Define.IsAsync)
- {
- #if UNITY_EDITOR
- string[] realPath = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
- foreach (string s in realPath)
- {
- string assetName = Path.GetFileNameWithoutExtension(s);
- string path = $"{assetBundleName}/{assetName}".ToLower();
- UnityEngine.Object resource = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(s);
- this.resourceCache[path] = resource;
- }
-
- this.bundles[assetBundleName] = new ABInfo(assetBundleName, null);
- return;
- #endif
- }
- AssetBundle assetBundle;
- using (AssetsBundleLoaderAsync assetsBundleLoaderAsync = EntityFactory.Create<AssetsBundleLoaderAsync>())
- {
- assetBundle = await assetsBundleLoaderAsync.LoadAsync(assetBundleName);
- }
- if (!assetBundle.isStreamedSceneAssetBundle)
- {
- // 异步load资源到内存cache住
- UnityEngine.Object[] assets;
- using (AssetsLoaderAsync assetsLoaderAsync = EntityFactory.Create<AssetsLoaderAsync, AssetBundle>(assetBundle))
- {
- assets = await assetsLoaderAsync.LoadAllAssetsAsync();
- }
- foreach (UnityEngine.Object asset in assets)
- {
- string path = $"{assetBundleName}/{asset.name}".ToLower();
- this.resourceCache[path] = asset;
- }
- }
-
- this.bundles[assetBundleName] = new ABInfo(assetBundleName, assetBundle);
- }
- public override void Dispose()
- {
- if (this.Id == 0)
- {
- return;
- }
- base.Dispose();
- foreach (var abInfo in this.bundles)
- {
- abInfo.Value?.AssetBundle?.Unload(true);
- }
-
- this.bundles.Clear();
- this.cacheDictionary.Clear();
- this.resourceCache.Clear();
- }
- }
- }
|