/// <summary> /// 卸载资源(Resources.UnloadAsset遍历卸载) /// </summary> private void unloadResource() { ResourceLogger.log(string.Format("卸载资源:{0}", AssetBundleName)); foreach (var loadedasset in mLoadedAssetMap) { var asset = loadedasset.Value; if (asset is GameObject) { ResourceLogger.log(string.Format("无法通过Resources.UnloadAsset卸载GameObject : {0}资源,后续会清空后通过Resources.UnloadUnsedAsset卸载!", asset.name)); } else if (asset is Component) { ResourceLogger.log(string.Format("无法通过Resources.UnloadAsset卸载Component : {0}资源,后续会清空后通过Resources.UnloadUnsedAsset卸载!", asset.name)); } else { //AssetDatabase模式不支持卸载资源, //因为并非真实的模拟AssetBundle资源加载行为,只是单纯的把所需资源自身加载进来 //Resources.UnloadAsset(loadedasset.Value); ResourceLogger.log(string.Format("假卸载资源:{0}的Asset : {1}", AssetBundleName, loadedasset.Value.name)); } } mLoadedAssetMap.Clear(); mIsReady = false; }
public override T loadAsset <T>(string assetname) { if (mIsReady) { if (mLoadedAssetMap.ContainsKey(assetname)) { return(mLoadedAssetMap[assetname] as T); } else { var assetpath = $"{AssetBundlePath}/{assetname}"; T asset = AssetDatabase.LoadAssetAtPath <T>(assetpath); if (asset != null) { mLoadedAssetMap.Add(assetname, asset); return(asset); } else { ResourceLogger.logErr(string.Format("找不到符合类型 : {0},资源名: {1},Asset : {2}资源!", typeof(T).GetType(), AssetBundlePath, assetname)); return(null); } } } else { ResourceLogger.logErr(string.Format("异常状态,AB资源:{0}未就绪就请求Asset资源:{1}", AssetBundlePath, assetname)); return(null); } }
/// <summary> /// 强制卸载指定资源(不管AB加载后属于哪一种类型,强制卸载) /// </summary> /// <param name="abname"></param> public void forceUnloadSpecificResource(string abname) { ResourceLoadType resourceloadtype = ResourceLoadType.NormalLoad; AbstractResourceInfo arinfo = null; foreach (var loadedabinfomap in mAllLoadedResourceInfoMap) { if (arinfo != null) { break; } foreach (var loadedabinfo in loadedabinfomap.Value) { if (loadedabinfo.Key.Equals(abname)) { arinfo = loadedabinfo.Value; resourceloadtype = loadedabinfomap.Key; break; } } } if (arinfo != null) { mAllLoadedResourceInfoMap[resourceloadtype].Remove(arinfo.AssetBundleName); arinfo.dispose(); ResourceLogger.log(string.Format("AB资源 : {0}已强制卸载!", abname)); } else { ResourceLogger.logErr(string.Format("AB资源 : {0}未被加载,无法强制卸载!", abname)); } }
/// <summary> /// AB加载携程 /// </summary> /// <returns></returns> private IEnumerator assetBundleLoadAsync() { while (true) { if (ABAsyncQueue.Count > 0) { CurrentLoadingAssetBundleLoader = ABAsyncQueue.Dequeue(); //检查是否已经同步加载完成 //如果异步加载AB时,同步请求来了,打断异步后续逻辑 //LoadState == ResourceLoadState.None表明同步加载该资源已经完成,无需再异步返回 if (CurrentLoadingAssetBundleLoader.LoadState == ResourceLoadState.None) { //ResourceLogger.logWar("有资源还未开始异步加载就被同步加载打断!"); } else { CurrentLoadingAssetBundleLoader.LoadState = ResourceLoadState.Loading; var abname = CurrentLoadingAssetBundleLoader.AssetBundleName; var abpath = AssetBundlePath.GetABLoadFullPath(abname); AssetBundleCreateRequest abrequest = null; #if UNITY_EDITOR //因为资源不全,很多资源丢失,导致直接报错 //这里临时先在Editor模式下判定下文件是否存在,避免AssetBundle.LoadFromFileAsync()直接报错 if (System.IO.File.Exists(abpath)) { abrequest = AssetBundle.LoadFromFileAsync(abpath); } else { Debug.LogError(string.Format("AB : {0}文件不存在!", CurrentLoadingAssetBundleLoader.AssetBundleName)); } #else abrequest = AssetBundle.LoadFromFileAsync(abpath); #endif yield return(abrequest); //如果异步加载AB时,同步请求来了,打断异步后续逻辑 //LoadState == ResourceLoadState.None表明同步加载该资源已经完成,无需再异步返回 if (CurrentLoadingAssetBundleLoader.LoadState == ResourceLoadState.None) { ResourceLogger.log(string.Format("资源 : {0}加载已完成,异步加载被打断!", abname)); } else { var assetbundle = abrequest.assetBundle; if (assetbundle == null) { ResourceLogger.logErr(string.Format("Failed to load AssetBundle : {0}!", CurrentLoadingAssetBundleLoader.AssetBundleName)); } CurrentLoadingAssetBundleLoader.onSelfABLoadComplete(assetbundle); } } CurrentLoadingAssetBundleLoader = null; } else { yield return(null); } } }
/// <summary> /// 获取AB加载全路径(含热更加载逻辑判定) /// </summary> /// <param name="abname"></param> /// <returns></returns> public static string GetABLoadFullPath(string abname) { //TODO: //热更逻辑路径判定 //if(包外有) // Application.persistentDataPath //{ // 返回包外资源路径 //} //else // Application.streamingAssetsPath //{ // 返回包内资源路径 //} var outterabfullpath = ABHotUpdatePath + abname; if (IsABExitInOutterPath(abname)) { ResourceLogger.log(string.Format("使用包外资源 : {0}", abname)); return(outterabfullpath); } else { ResourceLogger.log(string.Format("使用包内资源 : {0}", abname)); return(ABBuildinPath + abname); } }
public override void OnDoubleClick(Mobile from) { Title = "Accounts"; Author = from.Name; ClearPages(); ArrayList al = new ArrayList(ResourcePool.Resources.Values); al.Sort(); for (int i = 0; i < al.Count; i++) { if (al[i] is RDRedirect) { continue; } ResourceData rd = al[i] as ResourceData; string inv = rd.DescribeInvestment(from); AddLine(rd.Name + ":"); AddLine(inv); if (Pages[Pages.Length - 1].Lines.Length < 8) { AddLine(""); } } string ttemp = ResourceLogger.GetHistory(from); string[] history = ttemp.Split(new char[] { '\n' }); string line; foreach (string trans in history) { if (trans == "") { continue; } string[] tlines = trans.Split(new char[] { ' ' }); line = ""; foreach (string t in tlines) { if ((line.Length + t.Length + 1) <= 20) { line += t + " "; } else { AddLine(line); line = t + " "; } } AddLine(line); AddLine(""); } base.OnDoubleClick(from); }
/// <summary> /// 同步加载资源 /// </summary> private void loadAssetSync() { if (string.IsNullOrEmpty(AssetBundlePath)) { ResourceLogger.logErr(string.Format("找不到资源名 : {0}的资源!", AssetBundlePath)); } else { mResourceInfo = createAssetDatabaseInfo(AssetBundlePath); mResourceInfo.updateLastUsedTime(); } ///AssetDatabase模式下没有依赖资源的概念, ///所以一口气回调资源加载任务完成和上层逻辑回调 LoadState = ResourceLoadState.SelfComplete; LoadSelfResourceCompleteNotifier(this); LoadSelfResourceCompleteNotifier = null; LoadState = ResourceLoadState.AllComplete; mResourceInfo.mIsReady = true; LoadResourceCompleteCallBack(mResourceInfo); LoadResourceCompleteCallBack = null; // 资源加载完成后,AssetDatabaseLoader的任务就完成了,回收重用 AssetDatabaseLoaderFactory.recycle(this); }
/// <summary> /// 同步加载资源 /// </summary> private void loadAssetSync() { //通过资源名(即AB名)定位相关资源 var assetspath = AssetDatabase.GetAssetPathsFromAssetBundle(AssetBundleName); if (assetspath.Length == 0) { ResourceLogger.logErr(string.Format("找不到资源名 : {0}的资源!", AssetBundleName)); } else { mResourceInfo = createAssetDatabaseInfo(AssetBundleName, assetspath); mResourceInfo.updateLastUsedTime(); } ///AssetDatabase模式下没有依赖资源的概念, ///所以一口气回调资源加载任务完成和上层逻辑回调 LoadState = ResourceLoadState.SelfComplete; LoadSelfResourceCompleteNotifier(this); LoadSelfResourceCompleteNotifier = null; LoadState = ResourceLoadState.AllComplete; mResourceInfo.mIsReady = true; LoadResourceCompleteCallBack(mResourceInfo); LoadResourceCompleteCallBack = null; // 资源加载完成后,AssetDatabaseLoader的任务就完成了,回收重用 AssetDatabaseLoaderFactory.recycle(this); }
/// <summary> /// 开始资源加载任务 /// </summary> public void startLoad() { if (LoadState == ResourceLoadState.None) { LoadState = ResourceLoadState.Waiting; loadAsset(); } else if (LoadState == ResourceLoadState.Waiting) { ResourceLogger.logErr(string.Format("AB : {0}处于等待加载中状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName)); } else if (LoadState == ResourceLoadState.Loading) { ResourceLogger.logErr(string.Format("AB : {0}处于加载中状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName)); } else if (LoadState == ResourceLoadState.SelfComplete) { ResourceLogger.logErr(string.Format("AB : {0}已经处于自身加载完成状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName)); } else if (LoadState == ResourceLoadState.AllComplete) { ResourceLogger.logErr(string.Format("AB : {0}已经处于自身以及依赖AB加载完成状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName)); } else if (LoadState == ResourceLoadState.Error) { ResourceLogger.logErr(string.Format("AB:{0}处于Error状态,无法加载!", AssetBundleName)); } }
/// <summary> /// 加载所有Asset(比如Shader预加载) /// Note: /// 加载图集使用loadAllAsset<Sprite>()或者loadAsset<Sprite> /// </summary> /// <param name="assetname"></param> /// <returns></returns> public override void loadAllAsset <T>() { if (mIsReady) { if (!mIsAllAssetLoaded) { foreach (var assetpath in AssetsPath) { var allassets = AssetDatabase.LoadAllAssetsAtPath(assetpath); foreach (var asset in allassets) { var assetname = asset.name; if (!mLoadedAssetMap.ContainsKey(assetname)) { mLoadedAssetMap.Add(assetname, asset); } else { ResourceLogger.logErr(string.Format("资源名 : {0}里有同名资源!Asset资源 : {1}添加失败!请优化取名,避免重名Asset!", AssetBundleName, assetname)); } } } mIsAllAssetLoaded = true; } } }
/// <summary> /// 真正的请求资源 /// </summary> /// <param name="resname">资源AB名</param> /// <param name="completehandler">加载完成上层回调</param> /// <param name="loadtype">资源加载类型</param> /// <param name="loadmethod">资源加载方式</param> protected override void realRequestResource(string resname, LoadResourceCompleteHandler completehandler, ResourceLoadType loadtype = ResourceLoadType.NormalLoad, ResourceLoadMethod loadmethod = ResourceLoadMethod.Sync) { // 如果资源已经加载完成,直接返回 if (mAllLoadedResourceInfoMap[ResourceLoadType.NormalLoad].ContainsKey(resname)) { completehandler(mAllLoadedResourceInfoMap[ResourceLoadType.NormalLoad][resname]); if (loadtype > ResourceLoadType.NormalLoad) { updateLoadedResourceInfoLoadType(resname, ResourceLoadType.NormalLoad, loadtype); } } else if (mAllLoadedResourceInfoMap[ResourceLoadType.Preload].ContainsKey(resname)) { completehandler(mAllLoadedResourceInfoMap[ResourceLoadType.Preload][resname]); if (loadtype > ResourceLoadType.Preload) { updateLoadedResourceInfoLoadType(resname, ResourceLoadType.Preload, loadtype); } } else if (mAllLoadedResourceInfoMap[ResourceLoadType.PermanentLoad].ContainsKey(resname)) { completehandler(mAllLoadedResourceInfoMap[ResourceLoadType.PermanentLoad][resname]); } else { // 确保同一个资源加载的Loader是同一个 // 保证同一个资源加载完成时上层所有加载该资源的回调正确 AssetBundleLoader abloader = null; if (mABRequestTaskMap.ContainsKey(resname)) { abloader = mABRequestTaskMap[resname]; // 之前有请求resname资源,但还未完成 // 比如先异步请求resname,在异步完成前来了一个同步请求resname // 修改加载方式并添加回调,调用同步加载方式,异步加载会在同步加载完成时一起回调 abloader.LoadMethod = loadmethod; abloader.LoadType = loadtype; abloader.LoadABCompleteCallBack += completehandler; abloader.LoadSelfABCompleteNotifier = onABLoadCompleteNotifier; if (loadmethod == ResourceLoadMethod.Sync) { ResourceLogger.log(string.Format("请求同步加载一个正在异步加载的资源 : {0}", abloader.AssetBundleName)); //重置AB加载状态,走同步加载模式 abloader.LoadState = ResourceLoadState.None; abloader.startLoad(); } } else { abloader = createABLoader(resname); abloader.LoadMethod = loadmethod; abloader.LoadType = loadtype; abloader.LoadABCompleteCallBack = completehandler; abloader.LoadSelfABCompleteNotifier = onABLoadCompleteNotifier; mABRequestTaskMap.Add(resname, abloader); abloader.startLoad(); } } }
/// <summary> /// 卸载指定类型不再使用的资源(Note:不支持卸载常驻资源类型) /// </summary> /// <param name="resourceloadtype">资源加载类型</param> protected void unloadSpecificLoadTypeUnsedResource(ResourceLoadType resourceloadtype) { if (resourceloadtype == ResourceLoadType.PermanentLoad) { ResourceLogger.logErr("不允许卸载常驻AB资源!"); return; } doUnloadSpecificLoadTypeUnsedResource(resourceloadtype); }
/// <summary> /// 异步加载任务入队列 /// </summary> /// <param name="abl"></param> public static void enqueue(AssetBundleLoader abl) { if (abl.LoadMethod == ResourceLoadMethod.Async) { ABAsyncQueue.Enqueue(abl); } else { ResourceLogger.logErr(string.Format("严重错误,同步加载资源 : {0} 不应该添加到异步加载队列里!", abl.AssetBundleName)); } }
/* * /// <summary> * /// 为AB添加指定owner的引用 * /// 所有owner都销毁则ab引用计数归零可回收 * /// </summary> * /// <param name="owner"></param> * private void retainOwner(UnityEngine.Object owner) * { * if (owner == null) * { * ResourceLogger.logErr(string.Format("引用对象不能为空!无法为资源:{0}添加引用!", AssetBundleName)); * return; * } * * foreach (var referenceowner in mReferenceOwnerList) * { * if (owner.Equals(referenceowner)) * { * return; * } * } * * System.WeakReference wr = new System.WeakReference(owner); * mReferenceOwnerList.Add(wr); * } * * /// <summary> * /// 获取AB有效的引用对象计数 * /// </summary> * /// <returns></returns> * private int updateOwnerReference() * { * for (int i = 0; i < mReferenceOwnerList.Count; i++) * { * UnityEngine.Object o = (UnityEngine.Object)mReferenceOwnerList[i].Target; * if (!o) * { * mReferenceOwnerList.RemoveAt(i); * i--; * } * } * return mReferenceOwnerList.Count; * } */ /// <summary> /// 卸载AB(AssetBundle.Unload(true)的形式) /// </summary> private void unloadAssetBundle() { ResourceLogger.log(string.Format("卸载AB:{0}", AssetBundleName)); if (Bundle != null) { // 索引计数为零时调用释放AB和Asset Bundle.Unload(true); } Bundle = null; mIsReady = false; }
/// <summary> /// 打印所有AB依赖信息 /// </summary> public void printAllResourceDpInfo() { foreach (var abinfo in mAssetBundleDpMap) { ResourceLogger.log(string.Format("AB Name:{0}", abinfo.Key)); foreach (var dpfile in abinfo.Value) { ResourceLogger.log(string.Format(" DP AB Name:{0}", dpfile)); } } }
/// <summary> /// 添加指定资源到白名单 /// Note: /// 默认白名单里的资源都以ResourceLoadType.Preload方式加载 /// </summary> /// <param name="resname">资源名(既AB名)</param> public void addToWhiteList(string resname) { if (!mResourceWhileListMap.ContainsKey(resname)) { mResourceWhileListMap.Add(resname, resname); } else { ResourceLogger.logErr(string.Format("资源 : {0}重复添加白名单!", resname)); } }
/// <summary> /// 获取指定加载类型的已加载资源信息映射Map /// </summary> /// <param name="loadtype">资源加载类型</param> /// <returns></returns> public Dictionary <string, AbstractResourceInfo> getSpecificLoadTypeARIMap(ResourceLoadType loadtype) { if (mAllLoadedResourceInfoMap.ContainsKey(loadtype)) { return(mAllLoadedResourceInfoMap[loadtype]); } else { ResourceLogger.logErr(string.Format("找不到资源类型 : {0}的已加载AB信息!", loadtype)); return(null); } }
/// <summary> /// 启动AB异步加载任务携程 /// </summary> public void startABAsyncLoad() { if (IsLoadStart == false) { CoroutineManager.Singleton.StartCoroutine(assetBundleLoadAsync()); IsLoadStart = true; } else { ResourceLogger.logErr("AB异步加载任务携程已经启动!不能重复开启!"); } }
/// <summary> /// 检查AB包外目录,不存在则创建一个 /// </summary> public static void CheckAndCreateABOutterPathFolder() { if (Directory.Exists(ABHotUpdatePath)) { ResourceLogger.log(string.Format("AB包外目录:{0}已存在!", ABHotUpdatePath)); } else { ResourceLogger.log(string.Format("AB包外目录:{0}不存在,新创建一个!", ABHotUpdatePath)); Directory.CreateDirectory(ABHotUpdatePath); } }
/// <summary> /// 开始资源加载卸载统计 /// </summary> public void startResourceLoadAnalyse() { if (ResourceLoadAnalyseSwitch) { ResourceLoadAnalyseStart = true; ResourceLoadAnalyseMap.Clear(); ResourceLogger.log("开启AB加载统计!"); } else { ResourceLogger.logErr("请先开启AB资源加载分析开关!"); } }
/// <summary> /// 更新已加载AB的加载类型 /// </summary> /// <param name="resname">资源名</param> /// <param name="oldloadtype">旧的加载类型</param> /// <param name="newloadtype">新的家在类型</param> protected void updateLoadedResourceInfoLoadType(string resname, ResourceLoadType oldloadtype, ResourceLoadType newloadtype) { if (mAllLoadedResourceInfoMap[oldloadtype].ContainsKey(resname)) { var abi = mAllLoadedResourceInfoMap[oldloadtype][resname]; mAllLoadedResourceInfoMap[newloadtype].Add(resname, abi); mAllLoadedResourceInfoMap[oldloadtype].Remove(resname); ResourceLogger.log(string.Format("已加载的资源 : {0}从资源类型 : {1}更新到资源类型 : {2}!", resname, oldloadtype, newloadtype)); } else { ResourceLogger.logErr(string.Format("资源类型 : {0}里找不到已加载的资源 : {1},无法更新该资源的加载类型!", oldloadtype, resname)); } }
/// <summary> /// AB资源加载完成 /// </summary> public void onSelfABLoadComplete(AssetBundle ab = null) { ResourceLogger.log(string.Format("AB:{0}自身加载完成!", AssetBundleName)); mABInfo = AssetBundleModule.createAssetBundleInfo(AssetBundleName, ab); mABInfo.updateLastUsedTime(); LoadState = ResourceLoadState.SelfComplete; // 通知上层自身AB加载完成,移除加载任务 LoadSelfABCompleteNotifier(this); LoadSelfABCompleteNotifier = null; loadDepAssetBundle(); }
/// <summary> /// 加载资源 /// </summary> private void loadAsset() { ResourceLogger.log(string.Format("加载资源:{0}", AssetBundleName)); //暂时默认都当同步处理 if (LoadMethod == ResourceLoadMethod.Sync) { LoadState = ResourceLoadState.Loading; loadAssetSync(); } else { LoadState = ResourceLoadState.Loading; loadAssetSync(); } }
/// <summary> /// 加载自身AB /// </summary> private void loadSelfAssetBundle() { ResourceLogger.log(string.Format("加载AB:{0}", AssetBundleName)); if (LoadMethod == ResourceLoadMethod.Sync) { LoadState = ResourceLoadState.Loading; loadAssetBundleSync(); } else { //异步加载AB修改成限制携程数量,入队列的形式 //ModuleManager.Singleton.getModule<ResourceModuleManager>().StartCoroutine(loadAssetBundleAsync()); AssetBundleAsyncQueue.enqueue(this); } }
/// <summary> AB加载完成通知(用于更新AB加载管理) /// </summary> /// <param name="abl">AB加载任务信息</param> private void onABLoadCompleteNotifier(AssetBundleLoader abl) { var abname = abl.AssetBundleName; if (mABRequestTaskMap.ContainsKey(abname)) { mABRequestTaskMap.Remove(abname); mAllLoadedResourceInfoMap[abl.LoadType].Add(abname, abl.ABInfo); //AB加载数据统计 if (ResourceLoadAnalyse.Singleton.ResourceLoadAnalyseSwitch) { ResourceLoadAnalyse.Singleton.addResourceLoadedTime(abname); } } else { ResourceLogger.logErr(string.Format("收到不在加载任务请求队列里的AB:{0}加载完成回调!", abname)); } }
/// <summary> /// 为AB添加指定owner的引用 /// 所有owner都销毁则ab引用计数归零可回收 /// </summary> /// <param name="owner"></param> protected void retainOwner(UnityEngine.Object owner) { if (owner == null) { ResourceLogger.logErr(string.Format("引用对象不能为空!无法为资源:{0}添加引用!", AssetBundlePath)); return; } foreach (var referenceowner in mReferenceOwnerList) { if (owner.Equals(referenceowner)) { return; } } System.WeakReference wr = new System.WeakReference(owner); mReferenceOwnerList.Add(wr); }
/// <summary> /// 打印当前资源所有使用者信息以及索引计数(开发用) /// </summary> public void printAllLoadedResourceOwnersAndRefCount() { ResourceLogger.log("Normal Loaded AssetDatabase Info:"); foreach (var adi in mAllLoadedResourceInfoMap[ResourceLoadType.NormalLoad]) { adi.Value.printAllOwnersNameAndRefCount(); } ResourceLogger.log("Preload Loaded AssetDatabase Info:"); foreach (var adi in mAllLoadedResourceInfoMap[ResourceLoadType.Preload]) { adi.Value.printAllOwnersNameAndRefCount(); } ResourceLogger.log("Permanent Loaded AssetDatabase Info:"); foreach (var adi in mAllLoadedResourceInfoMap[ResourceLoadType.PermanentLoad]) { adi.Value.printAllOwnersNameAndRefCount(); } }
/// <summary> /// 依赖AB加载完成回调 /// </summary> /// <param name="resinfo">ab加载信息</param> private void onDepABLoadComplete(AbstractResourceInfo resinfo) { var abinfo = resinfo as AssetBundleInfo; ResourceLogger.log(string.Format("依赖AB:{0}加载成功!", abinfo.AssetBundleName)); mDepAssetBundleInfoList.Add(abinfo); #if UNITY_EDITOR //Editor模式下的调试功能 // 移除已经加载过的,存储来测试查看用 mUnloadedAssetBundleName.Remove(abinfo.AssetBundleName); #endif mLoadedDepABCount++; // 作为依赖AB时并不会触发getAsset || instantiateAsset之类的接口, // 依赖于Unity加载依赖AB自动还原的机制,所以这里我们需要手动更新AB资源的最近使用时间 abinfo.updateLastUsedTime(); if (mLoadedDepABCount == mDepABCount) { allABLoadedComplete(); } }
/// <summary> /// 实例化指定Asset(上层获取并绑定Asset实例化GameObject对象接口) /// </summary> /// <param name="assetname"></param> /// <returns></returns> public override GameObject instantiateAsset(string assetname) { var goasset = loadAsset <GameObject>(assetname); if (goasset != null) { var goinstance = GameObject.Instantiate <GameObject>(goasset); //不修改实例化后的名字,避免上层逻辑名字对不上 //goinstance.name = goasset.name; // 绑定owner对象,用于判定是否还有有效对象引用AB资源 retainOwner(goinstance); updateLastUsedTime(); return(goinstance); } else { ResourceLogger.logErr(string.Format("AB:{0}里加载GameObject Asset:{1}失败!", AssetBundleName, assetname)); return(null); } }
/// <summary> /// 打印当前AB所有使用者信息以及索引计数(开发用) /// </summary> public void printAllOwnersNameAndRefCount() { ResourceLogger.log(string.Format("AB Name: {0}", AssetBundlePath)); ResourceLogger.log(string.Format("Ref Count: {0}", RefCount)); if (mReferenceOwnerList.Count == 0) { ResourceLogger.log("Owners Name : None"); } else { ResourceLogger.log("Owners Name :"); for (int i = 0, length = mReferenceOwnerList.Count; i < length; i++) { if (mReferenceOwnerList[i].Target != null) { ResourceLogger.log(string.Format("owner[{0}] : {1}", i, mReferenceOwnerList[i].Target.ToString())); } } } ResourceLogger.log(string.Format("Last Used Time: {0}", LastUsedTime)); }