using System.Collections.Generic; using Fort23.Core; using Fort23.UTool; using UnityEngine; using Utility; namespace Core.AssetLoadTool.Asset { public class BundleLoadBasic : LoadTaskBasic { public List ownTask = new List(); protected string url; private float progress; protected object userData; private Map _bundleAsset = new Map(); public AssetBundle currBundle { get { return _currBundle; } } protected AssetBundle _currBundle; protected System.Action callBack; protected List m_dependenceTasks = new List(); protected bool isAwaitDependencies; protected bool _isUnloadType; public string bundleName; public void InitBundle(string bundleName, bool isUnloadType, System.Action callBack) { // Debug.Log("加载bunlde"+bundleName); _isUnloadType = isUnloadType; loadState = LoadState.Init; AddCallBack(callBack); this.bundleName = bundleName; LoadDependencies(bundleName); } public void LoadDependencies(string bundleName) { string[] dependencies = AssetBundleLoadManager.Instance.GetBundleDependencies(bundleName); if (dependencies != null && dependencies.Length > 0) { m_dependenceTasks = new List(); for (int i = 0; i < dependencies.Length; i++) { string depBundleName = dependencies[i]; BundleLoadBasic task = AssetBundleLoadManager.Instance.AddBundleTask(depBundleName, null, this); m_dependenceTasks.Add(task); } isAwaitDependencies = true; loadState = LoadState.Await; AssetBundleLoadManager.Instance.dependenciesBuffer.Add(this); } else { loadState = LoadState.Load; StartLoad(); } } public bool AwaitDependenceLoadEnd() { for (int i = 0; i < m_dependenceTasks.Count; i++) { if (!m_dependenceTasks[i].IsLoadEnd()) { return false; } } AwaitDependenciesFinish(); return true; } protected void AwaitDependenciesFinish() { isAwaitDependencies = false; if (loadState == LoadState.Await) { // loadState = LoadState.End; // callBack?.Invoke(this, userData); loadState = LoadState.Load; StartLoad(); } } protected void LoadFinish(AssetBundle assetBundle) { _currBundle = assetBundle; if (_currBundle == null) { LogTool.Error("budnle空的" + url + "__" + bundleName); return; } // if (isAwaitDependencies) // { // loadState = LoadState.Await; // } // else { loadState = LoadState.End; callBack?.Invoke(this, userData); } } public void AddCallBack(System.Action callBack) { if (loadState == LoadState.End) { if (callBack != null) { callBack(this, userData); } return; } this.callBack += callBack; } public void AddOwnTask(LoadTaskBasic taskBasic) { if (taskBasic == null) { return; } if (ownTask.Contains(taskBasic)) { return; } ownTask.Add(taskBasic); } public void RemoveAsset(string assetName) { if (_bundleAsset.TryGetValue(assetName, out LoadInfoAsset loadInfoAsset)) { loadInfoAsset.count--; } } public async CTask LoadAsset(string assetName) where T : Object { if (_bundleAsset.TryGetValue(assetName, out LoadInfoAsset loadInfoAsset)) { loadInfoAsset.count++; if (loadInfoAsset.asset == null) { _bundleAsset.Remove(assetName); } else { return (T)loadInfoAsset.asset; } } if (_currBundle == null) { LogTool.Error("budnle已经空" + url + "__" + bundleName); return default; } using (await CoroutineLockComponent.Instance.Wait(assetName)) { if (_bundleAsset.TryGetValue(assetName, out loadInfoAsset)) { return (T)loadInfoAsset.asset; } CTask cTask = CTask.Create(false); loadInfoAsset = new LoadInfoAsset(); AssetBundleRequest assetBundleRequest= _currBundle.LoadAssetAsync(assetName); assetBundleRequest.completed += delegate(AsyncOperation obj) { loadInfoAsset.asset = assetBundleRequest.asset; loadInfoAsset.count = 1; _bundleAsset.Add(assetName, loadInfoAsset); cTask.SetResult(); }; // loadInfoAsset.asset = _currBundle.LoadAsset(assetName); // loadInfoAsset.count = 1; await cTask; } return (T)loadInfoAsset.asset; } public void RemoveOwnTask(LoadTaskBasic taskBasic) { ownTask.Remove(taskBasic); UnloadBundle(); } public void UnloadBundle() { if (ownTask.Count <= 0) { Dispose(); } } private void Dispose() { if (loadState == LoadState.Load) { return; } for (_bundleAsset.Begin(); _bundleAsset.Next();) { if (_bundleAsset.Value.asset is GameObject) { Object.DestroyImmediate(_bundleAsset.Value.asset, true); } else { Resources.UnloadAsset(_bundleAsset.Value.asset); } } _bundleAsset.Clear(); for (int i = 0; i < m_dependenceTasks.Count; i++) { m_dependenceTasks[i].RemoveOwnTask(this); } m_dependenceTasks.Clear(); if (_currBundle != null) { // Debug.Log("卸载bunlde"+bundleName); _currBundle.Unload(_isUnloadType); _currBundle = null; } AssetBundleLoadManager.Instance.RemoveBundleTask(this); loadState = LoadState.Disposed; } } }