using UnityEngine; namespace BF { public class AssetObject : AssetObjectBase { private BFEvent completes; private AssetBundleRequest async; //资源被指定直接加载。设置为同步之后再也不会变更为false. private bool needSync; public AssetObject(string assetPath, System.Type type, bool needSync = false) : base(assetPath, type) { completes = new BFEvent(); this.needSync = needSync; } public void LoadComplete(Object asset) { LoadStatus = EAssetLoadStatus.Complete; Asset = asset; } public void LoadAsync(System.Action callback) { ++RefCount; if (EAssetLoadStatus.Complete == LoadStatus) { callback(AssetPath, Asset); return; } if (EAssetLoadStatus.Unloading == LoadStatus) { LoadStatus = EAssetLoadStatus.Complete; callback(AssetPath, Asset); return; } if (EAssetLoadStatus.Error == LoadStatus) { LoadStatus = EAssetLoadStatus.Wait; // 加载出现错误,重新加载 } completes += callback; } public void LoadSync() { needSync = true; //当依赖的bundle加载完成从 startasync 函数进入,资源会直接走同步加载接口 ++RefCount; BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] assetobject base LoadSync refcount : {0}, async : {1}, Asset : {2}", RefCount, async, Asset); if (async != null && Asset == null) //bundle 加载完成,但是资源还在加载 unity2018新特性 同步返回异步结果 { AsyncCompleted(async); } else if(Asset != null) { LoadStatus = EAssetLoadStatus.Complete; } } public override bool Unload(bool immediately) { if (RefCount == 0) return false; --RefCount; BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] assetobject base unload refcount : {0}", RefCount); if (RefCount == 0) { completes.Clear(); LoadStatus = EAssetLoadStatus.Unloading; //开始卸载 if (immediately) { UnloadCountdown(true); return false; } else { unloadCountdownTime = Time.time + ResourceManager.TIME_DELAY_UNLOAD; return true; } } return false; } protected override bool OnUnloadComplete() { BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "[ResMgr] AssetObject OnUnloadComplete AssetPath : {0}, LoadStatus : {1}", AssetPath, LoadStatus); if (EAssetLoadStatus.Complete == LoadStatus || EAssetLoadStatus.Error == LoadStatus) //等待异步加载完成 { return false; } LoadStatus = EAssetLoadStatus.Unloaded; completes.Clear(); BFMain.Instance.ResMgr.Unload(this, true); return true; } public void UnloadAsset() { if (!(Asset is GameObject)) //gameobject 无法使用这个接口,只能依赖于 Resources.UnloadUnusedAssets() { Resources.UnloadAsset(Asset); } Asset = null; } public void StartLoadAsset(AssetBundle ab) { BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "StartAsync ab : {0}, AssetPath : {1}, AssetType : {2}", ab, AssetPath, AssetType); if (ab == null) { LoadEnd(null); } else { if (needSync) { var asset = ab.LoadAsset(AssetPath, AssetType); LoadEnd(asset); } else { async = ab.LoadAssetAsync(AssetPath, AssetType); async.completed += AsyncCompleted; } } } private void AsyncCompleted(AsyncOperation ao) { async.completed -= AsyncCompleted; LoadEnd(async.asset); } private void LoadEnd(Object obj) { BFLog.LogDebug(BFLog.DEBUG_RESMGR, "green", "LoadEnd asset : {0}, refcount : {1} callback : {2}, LoadStatus : {3}", obj, RefCount, completes.CallbackCount(), LoadStatus); Asset = obj; if (obj == null) { LoadStatus = EAssetLoadStatus.Error; } else { LoadStatus = EAssetLoadStatus.Complete; } completes.Invoke(AssetPath, Asset); completes.Clear(); } public void AssetDataBaseLoadEnd(Object obj) { LoadEnd(obj); } } }