private static void GetCommonRes_OnRunTime(ref ResNode reslut, string AssetBundleName, string AssetName, System.Type t) { if (!isOnRunTimeMode) { return; } string str = AssetBundleName + AssetName; string hashCode = str.GetHashCode().ToString(); if (m_CommonResNodeTable.TryGetValue(hashCode, out reslut)) { reslut.AddRef(); return; } Dictionary <string, UnityEngine.Object> assetTable = null; if (m_CommonAssetsTable.TryGetValue(AssetBundleName, out assetTable)) { UnityEngine.Object asset = null; if (assetTable.TryGetValue(AssetName, out asset)) { reslut = AllocResNode(hashCode.ToString()); reslut.Clear(); if (null == reslut.config) { reslut.config = new ResConfigData(); } reslut.config.AssetName = AssetName; reslut.config.AssetBundleName = AssetBundleName; reslut.config.AssetGUID = hashCode; reslut.isAsync = false; reslut.FillAssets(asset); reslut.status = ResNodeStatus.LoadFinish; reslut.AddRef(); reslut.assetType = AssetBundleName.EndsWith(AssetBundleManager.PrefabVariant) ? AssetType.Asset_Prefab : AssetType.Asset_CommonAssets; m_CommonResNodeTable.Add(hashCode, reslut); } else { AssetBudleLog("在通用资源包:" + AssetBundleName + "找不到资源:" + AssetName); } } return; }
private static void GetCommonRes(ref ResNode reslut, ResConfigData config) { if (!isOnRunTimeMode) { return; } if (m_CommonResNodeTable.TryGetValue(config.AssetGUID, out reslut)) { reslut.AddRef(); return; } Dictionary <string, UnityEngine.Object> assetTable = null; if (m_CommonAssetsTable.TryGetValue(config.AssetBundleName, out assetTable)) { UnityEngine.Object asset = null; if (assetTable.TryGetValue(config.AssetName, out asset)) { reslut = AllocResNode(config.AssetGUID); reslut.Clear(); reslut.config = config; reslut.assetType = config.AssetBundleName.EndsWith(AssetBundleManager.PrefabVariant) ? AssetType.Asset_Prefab : AssetType.Asset_CommonAssets; reslut.isAsync = false; reslut.FillAssets(asset); reslut.status = ResNodeStatus.LoadFinish; reslut.AddRef(); m_CommonResNodeTable.Add(config.AssetGUID, reslut); } else { AssetBudleLog("在通用资源包:" + config.AssetBundleName + "找不到资源:" + config.AssetName); } } return; }
/// <summary> /// 获取资源,资源内部使用引用计数来管理资源,切勿乱调用,一个get,一个delete /// </summary> /// <param name="config"></param> /// <returns></returns> private static ResNode GetAnimationClipResource(ResConfigData config) { if (!isVaild) { return(null); } if (string.IsNullOrEmpty(config.AssetBundleName)) { return(null); } ResNode res = null; //先看看是不是通用资源 GetCommonRes(ref res, config); if (null != res) { return(res); } if (IsUnionDependenicesAssetBundle(config.AssetBundleName)) { if (!config.fromReference) { AssetBudleLog(StringHelper.BuildString("资源错误--uniondepndenices不能单独加载!:", config.AssetName)); return(res); } } //先看看缓存里是不是有这个资源 res = GetCacheAnimationClipResource(config); if (null != res) { m_AnimationClipResTable.Add(res.instanceID, res); //判断一下这个资源是否是异步加载的 if (res.isAsync) { if (!res.isLoadFinish) { BuildResNodeWhenInAsyncLoading <AnimationClip>(ref res, config); //Debug.LogWarning(StringHelper.BuildString(config.AssetName, "正在异步加载中,请调用ResNode.isLoadFinish查看是否完成")); } } res.AddRef(); return(res); } int InstanceID = GUIDToInstanceID(config.AssetGUID); //所需的资源已经存在 if (m_AnimationClipResTable.TryGetValue(InstanceID, out res)) { //判断一下这个资源是否是异步加载的 if (res.isAsync) { if (!res.isLoadFinish) { BuildResNodeWhenInAsyncLoading <AnimationClip>(ref res, config); //Debug.LogWarning(StringHelper.BuildString(config.AssetName, "正在异步加载中,请调用ResNode.isLoadFinish查看是否完成")); } } //同时增加这个资源的引用计数 res.AddRef(); } else { res = BuildAnimationClipResNode(config); if (res != null) { m_AnimationClipResTable.Add(res.instanceID, res); } } if (null != res) { res.assetType = AssetType.Asset_AnimationClip; } return(res); }
/// <summary> /// 异步构建ResNode,会立即返回一个ResNode,这个ResNode只是一个标示,里面没有资源! /// </summary> /// <typeparam name="T"></typeparam> /// <param name="config"></param> /// <param name="callBack"></param> /// <param name="userDataObj"></param> /// <returns></returns> private static ResNode BuildAnimationClipResNodeAsync(ResConfigData config, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj) { ResNode res = null; int assetGUID = GUIDToInstanceID(config.AssetGUID); //如果这个资源正在要卸载的列表里,移除掉,免得资源加载完就被卸载了 res = GetResNodeFromNeedToUnLoadAsset(assetGUID); if (res != null) { res.AddRef(); m_AnimationClipResTable.Add(assetGUID, res); GenerateResCallBack(res, config, callBack, userDataObj); res.config = config; return(res); } res = GetCacheAnimationClipResource(config); //如果缓存里有这个资源结点 if (res != null) { res.AddRef(); m_AnimationClipResTable.Add(assetGUID, res); //看看资源是不是已经加载完成了。 if (!res.isLoadFinish) { GenerateResCallBack(res, config, callBack, userDataObj); } else { PushToResDelayCallBackList(res, config, callBack, userDataObj); } res.config = config; return(res); } //没有在缓存里,就看看是不是已经在使用了 if (m_AnimationClipResTable.ContainsKey(assetGUID)) { res = m_AnimationClipResTable[assetGUID]; res.AddRef(); //看看资源是不是已经加载完成了。 if (!res.isLoadFinish) { GenerateResCallBack(res, config, callBack, userDataObj); } else { PushToResDelayCallBackList(res, config, callBack, userDataObj); } res.config = config; return(res); } /*没有缓存,没有在使用,说明这是一个全新的请求,直接走下面,创建一个新的请求*/ res = GetAnimationClipPackgeAsync(config, AnimationClipPackageCallBack, callBack, userDataObj); return(res); }
/// <summary> /// 异步取得Prefab,返回值只是一个标示,没有资源,资源在回调中 /// </summary> /// <param name="config">资源配置</param> /// <param name="callBack">回调</param> /// <param name="userDataObj">用户数据</param> private static ResNode GetPrefabAsync(UnionResConfigData config, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj = null, AssetLoadPriority priority = AssetLoadPriority.Priority_Normal) { if (!isVaild) { return(null); } ResNode reslut = null; config.priority = priority; //编辑器下无异步加载 if (!isOnRunTimeMode) { reslut = GetPrefab(config); PushToResDelayCallBackList(reslut, config, callBack, userDataObj); return(reslut); } if (config.unionIndx < 0 || config.startIndex < 0 || config.dataLength <= 0) { Debug.LogWarning("confing is invalid:" + config.AssetName); return(null); } GetCommonRes(ref reslut, config); if (null != reslut) { PushToResDelayCallBackList(reslut, config, callBack, userDataObj); return(reslut); } int InstanceID = GUIDToInstanceID(config.AssetGUID); reslut = GetResNodeFromNeedToUnLoadAsset(InstanceID); if (null != reslut)//表里面有这个预制体的话,说明依赖已经加载完毕 { reslut.AddRef(); m_PrefabResTable.Add(InstanceID, reslut); GeneratePrefabCallBack(reslut, config, callBack, userDataObj); reslut.config = config; return(reslut); } reslut = GetCachePrefabResource(config); if (null != reslut)//表里面有这个预制体的话,说明依赖已经加载完毕 { reslut.AddRef(); m_PrefabResTable.Add(InstanceID, reslut); if (!reslut.isLoadFinish) { GeneratePrefabCallBack(reslut, config, callBack, userDataObj); } else { PushToResDelayCallBackList(reslut, config, callBack, userDataObj); } reslut.config = config; return(reslut); } //先看看表中是否有这个配置 m_PrefabResTable.TryGetValue(InstanceID, out reslut); if (null == reslut) { m_AsyncLoadingDependicensPrefabResNode.TryGetValue(InstanceID, out reslut); if (null == reslut) { reslut = AllocResNode(config.AssetGUID); reslut.config = config; reslut.assetType = AssetType.Asset_Prefab; reslut.status = ResNodeStatus.WatingForLoad; reslut.isAsync = true; bool b = LoadDependenicesAsync(config); //依赖加载失败 if (!b) { reslut = null; return(null); } m_AsyncLoadingDependicensPrefabResNode.Add(InstanceID, reslut); } reslut.AddRef(); GeneratePrefabCallBack(reslut, config, callBack, userDataObj); reslut.config = config; } else { //再看看加载列表中是否有这个配置,有就等待回调 if (m_PrefabRequestTable.ContainsKey(InstanceID)) { reslut.AddRef(); GeneratePrefabCallBack(reslut, config, callBack, userDataObj); } else { PushToResDelayCallBackList(reslut, config, callBack, userDataObj); } reslut.AddRef(); reslut.config = config; } return(reslut); }
private static ResNode GetPrefab(UnionResConfigData config) { if (!isVaild) { return(null); } if (isOnRunTimeMode) { if (config.unionIndx < 0 || config.startIndex < 0 || config.dataLength <= 0) { Debug.LogWarning("confing is invalid:" + config.AssetName); return(null); } } ResNode res = null; //看看是不是通用资源 GetCommonRes(ref res, config); if (null != res) { return(res); } res = GetCachePrefabResource(config); if (null != res) { res.AddRef(); m_PrefabResTable.Add(res.instanceID, res); return(res); } double loadbegain = DateTime.Now.Ticks; int id = GUIDToInstanceID(config.AssetGUID); //如果还在异步加载中,这里是依赖的资源异步还没有完成 if (m_AsyncLoadingDependicensPrefabResNode.TryGetValue(id, out res)) { BuildPrefabWhenInAsyncLoading(ref res, config); res.AddRef(); return(res); } res = AllocResNode(id); if (m_PrefabResTable.TryGetValue(res.instanceID, out res)) { //如果是异步加载,这里是依赖资源加载完了,但是预制体本身还没有出来。 if (res.isAsync) { if (!res.isLoadFinish) { BuildResNodeWhenInAsyncLoading <GameObject>(ref res, config); } } res.AddRef(); return(res); } //非运行时模式,不需要去加载依 if (!isOnRunTimeMode) { GetPrefabResource(ref res, config); } else { /*加载完依赖项之后,再去加载目标资源,要检测目标资源是否成功 * 如果加载失败,要立刻释放这些资源。 */ if (LoadDependenices(config)) { //依赖资源都加载完了,是时候加载这个真正的预制体了 GetPrefabResource(ref res, config); if (null == res) { UnLoadDependenices(id); } } } if (null != res) { res.assetType = AssetType.Asset_Prefab; //SaveMemory(res); ReleaseDependenicesAssetBundleIfNeed(res); ReleaseAssetBundleIfNeed(res); //if(!SceneManager.isLoadingScene && !SceneManager.Instance.isMainCity()) //{ // loadbegain = GameUtil.TicksToSecond(DateTime.Now.Ticks - loadbegain); // if (loadbegain > 0.15f) // { // loadbegain *= 1000; // Debug.LogWarning("资源加载超过150ms,当前时间:" + loadbegain .ToString("F3") + ",资源名:" + res.AssetName + ",请预加载或者使用异步加载此资源"); // } //} } return(res); }
private static void GetCommonRes_OnEditor(ref ResNode reslut, string AssetBundleName, string AssetName, System.Type t) { if (isOnRunTimeMode) { return; } string str = AssetBundleName + AssetName; string hashCode = str.GetHashCode().ToString(); if (m_CommonResNodeTable.TryGetValue(hashCode, out reslut)) { reslut.AddRef(); return; } Dictionary <string, UnityEngine.Object> assetTable = null; UnityEngine.Object asset = null; /*编辑器下找不到资源,就去加载*/ if (m_CommonAssetsTable.TryGetValue(AssetBundleName, out assetTable)) { if (assetTable.TryGetValue(AssetName, out asset)) { reslut = AllocResNode(hashCode.ToString()); reslut.Clear(); if (null == reslut.config) { reslut.config = new ResConfigData(); } reslut.config.AssetName = AssetName; reslut.config.AssetBundleName = AssetBundleName; reslut.config.AssetGUID = hashCode; reslut.isAsync = false; reslut.FillAssets(asset); reslut.assetType = AssetBundleName.EndsWith(AssetBundleManager.PrefabVariant) ? AssetType.Asset_Prefab : AssetType.Asset_CommonAssets; reslut.AddRef(); m_CommonResNodeTable.Add(hashCode, reslut); } else { UnityEngine.Object[] assets = LoadAssetOnEditorFromAbInstance(AssetBundleName, AssetName, t); if (null != assets && assets.Length > 0) { assetTable = new Dictionary <string, UnityEngine.Object>(); foreach (UnityEngine.Object ob in assets) { assetTable.Add(ob.name, ob); } //再将东西取出来 asset = assetTable[AssetName]; reslut = AllocResNode(hashCode.ToString()); reslut.Clear(); reslut.FillAssets(asset); reslut.status = ResNodeStatus.LoadFinish; if (reslut.config == null) { reslut.config = new ResConfigData(); } reslut.config.AssetName = AssetName; reslut.config.AssetBundleName = AssetBundleName; reslut.config.AssetGUID = hashCode; reslut.isAsync = false; reslut.assetType = AssetBundleName.EndsWith(AssetBundleManager.PrefabVariant) ? AssetType.Asset_Prefab : AssetType.Asset_CommonAssets; reslut.AddRef(); m_CommonResNodeTable.Add(hashCode, reslut); } else { AssetBudleLog("在通用资源包:" + AssetBundleName + "找不到资源:" + AssetName); } } } else { UnityEngine.Object[] assets = LoadAssetOnEditorFromAbInstance(AssetBundleName, AssetName, t); if (null != assets && assets.Length > 0) { assetTable = new Dictionary <string, UnityEngine.Object>(); foreach (UnityEngine.Object ob in assets) { assetTable.Add(ob.name, ob); } m_CommonAssetsTable.Add(AssetBundleName, assetTable); //再将东西取出来 asset = assetTable[AssetName]; reslut = AllocResNode(hashCode.ToString()); reslut.Clear(); if (reslut.config == null) { reslut.config = new ResConfigData(); } reslut.config.AssetName = AssetName; reslut.config.AssetBundleName = AssetBundleName; reslut.config.AssetGUID = hashCode; reslut.isAsync = false; reslut.FillAssets(asset); reslut.status = ResNodeStatus.LoadFinish; reslut.assetType = AssetBundleName.EndsWith(AssetBundleManager.PrefabVariant) ? AssetType.Asset_Prefab : AssetType.Asset_CommonAssets; reslut.AddRef(); m_CommonResNodeTable.Add(hashCode, reslut); } else { AssetBudleLog("在通用资源包:" + AssetBundleName + "找不到资源:" + AssetName); } } return; }
/// <summary> /// 获取资源,资源内部使用引用计数来管理资源,切勿乱调用,一个get,一个delete /// </summary> /// <param name="config"></param> /// <returns></returns> private static void GetPrefabResource(ref ResNode result, UnionResConfigData config) { if (!isVaild) { return; } if (string.IsNullOrEmpty(config.AssetBundleName)) { return; } //先看看是不是通用资源 GetCommonRes(ref result, config); if (null != result) { return; } //先看看缓存里是不是有这个资源 result = GetCachePrefabResource(config); if (null != result) { m_PrefabResTable.Add(result.instanceID, result); //判断一下这个资源是否是异步加载的 if (result.isAsync) { if (!result.isLoadFinish) { BuildResNodeWhenInAsyncLoading <GameObject>(ref result, config); //Debug.LogWarning(StringHelper.BuildString(config.AssetName, "正在异步加载中,请调用ResNode.isLoadFinish查看是否完成")); } } result.AddRef(); return; } int InstanceID = GUIDToInstanceID(config.AssetGUID); //所需的资源已经存在 if (m_PrefabResTable.TryGetValue(InstanceID, out result)) { ////判断一下这个资源是否是异步加载的,预制体的这个在上层判断 //if (result.isAsync) //{ // if (!result.isLoadFinish) // { // BuildResNodeWhenInAsyncLoading<GameObject>(ref result, config); // //Debug.LogWarning(StringHelper.BuildString(config.AssetName, "正在异步加载中,请调用ResNode.isLoadFinish查看是否完成")); // } //} //同时增加这个资源的引用计数 result.AddRef(); } else { BuildPrefabResNode(ref result, config); if (result != null) { m_PrefabResTable.Add(result.instanceID, result); } } if (null != result) { result.assetType = AssetType.Asset_Prefab; } return; }
/// <summary> /// 异步构建ResNode,会立即返回一个ResNode,这个ResNode只是一个标示,里面没有资源! /// </summary> /// <typeparam name="T"></typeparam> /// <param name="config"></param> /// <param name="callBack"></param> /// <param name="userDataObj"></param> /// <returns></returns> private static void BuildPrefabResNodeAsync(ref ResNode res, UnionResConfigData config, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj) { int assetGUID = GUIDToInstanceID(config.AssetGUID); //缓存相关,已在上层判断 ////如果这个资源正在要卸载的列表里,移除掉,免得资源加载完就被卸载了 //RemoveNeedToUnLoadAsset(assetGUID); //ResNode CacheRes = GetCachePrefabResource(config); ////如果缓存里有这个资源结点 //if (CacheRes != null) //{ // //缓存中的Res应该要和传进来的Res一样! // if (null != res && CacheRes != res) // { // Debug.LogError("预制体异步加载超级bug"); // return; // } // res = CacheRes; // res.AddRef(); // m_PrefabResTable.Add(assetGUID, res); // //看看资源是不是已经加载完成了。 // if (m_LoadingAssetTable.ContainsKey(assetGUID)) // { // GenerateResCallBack(res, config, callBack, userDataObj); // } // else // { // //直接回调 // PushToResDelayCallBackList(res, config, callBack, userDataObj); // } // return; //} //else { //没有在缓存里,就看看是不是已经在使用了 if (m_PrefabResTable.ContainsKey(assetGUID)) { res = m_PrefabResTable[assetGUID]; res.AddRef(); //看看资源是不是已经加载完成了。 if (!res.isLoadFinish) { GenerateResCallBack(res, config, callBack, userDataObj); } else { PushToResDelayCallBackList(res, config, callBack, userDataObj); } return; } } /*没有缓存,没有在使用,说明这是一个全新的请求,直接走下面,创建一个新的请求*/ GetPrefabPackgeAsync(ref res, config, PrefabPackageCallBack, callBack, userDataObj); }
/// <summary> /// 异步构建package /// </summary> /// <param name="reslutTable"></param> /// <param name="config"></param> /// <param name="resourcePackageCallBack"></param> /// <param name="UserCallBack"></param> /// <param name="userDataObj"></param> /// <returns></returns> private static void BuildPacakgeAsync(ref ResNode result, Dictionary <int, ResNode> reslutTable, ResConfigData config, System.Action <ResourcePackageCallBackObj> resourcePackageCallBack, System.Action <ResConfigData, ResNode, System.Object> UserCallBack, System.Object userDataObj, bool isPrefabResNode = false) { string patch = AssetBundleManager.FullAssetPackagePathRoot + config.AssetBundleName; UnionResConfigData unionRes = config as UnionResConfigData; string abPath = config.AssetBundleName; if (unionRes != null) { patch = unionRes.UnionFilePath; abPath = unionRes.ShortUnionFilePath; } if (!m_RespackageTable.ContainsKey(abPath)) { AssetBudleLog("AssetBundle文件不存在!,路径:" + patch); return; } result = AllocResNode(config.AssetGUID); result.StartLoadedTime(); //预制体是预先创建好ResNode的,所以不能清除和增加引用,直接使用外部的即可 if (!isPrefabResNode) { result.Clear(); result.AddRef(); } result.config = config; result.isAsync = true; result.status = ResNodeStatus.WatingForLoad; AssetRequest are = null; are = AllocAssetRequest(result.instanceID); m_LoadingAssetList.Add(result.instanceID); are.Clear(); reslutTable.Add(result.instanceID, result); GenerateResCallBack(result, config, UserCallBack, userDataObj); ResourcePackage pakg = AllocResourcePackage(config.AssetBundleName); pakg.priority = config.priority; //已经有了 if (m_LoadedResourcePackage.Contains(pakg.instanceID)) { pakg.AddRef(); pakg.AddAsyncCallBackData(resourcePackageCallBack, BuildResourcePackageCallBackObj(pakg, result, config, UserCallBack, userDataObj)); PushToResourcePackageCallBackList(pakg.instanceID); } else { //如果卸载列表里,先移除掉,避免加载出来就被卸载了 RemoveNeedToUnLoadPackage(pakg.instanceID); //没有开启异步加载 if (!enabledAsyncLoadAssetFile) { pakg = GetResourcePackge(config); pakg.AddAsyncCallBackData(resourcePackageCallBack, BuildResourcePackageCallBackObj(pakg, result, config, UserCallBack, userDataObj)); PushToResourcePackageCallBackList(pakg.instanceID); return; } //全新的包 if (!m_ResourcePackageRequestTable.Contains(pakg.instanceID)) { pakg.Clear(); pakg.isAsync = true; pakg.filePatch = patch; FillUnioFileInfo(config as UnionResConfigData, pakg); EnQueueWaitForUpLoadAssetsFileAsyncRequestTable(pakg.instanceID); m_ResourcePackageRequestTable.Add(pakg.instanceID); } pakg.AddAsyncCallBackData(resourcePackageCallBack, BuildResourcePackageCallBackObj(pakg, result, config, UserCallBack, userDataObj)); pakg.AddRef(); } return; }