/// <summary> /// 不能获取预制体 /// </summary> /// <param name="t"></param> /// <param name="conf"></param> /// <returns></returns> public static ResNode GetAssets(AssetType t, ResConfigData conf) { ResNode res = null; if (null == conf) { return(res); } switch (t) { case AssetType.Asset_Prefab: UnionResConfigData unionCof = conf as UnionResConfigData; if (null == unionCof) { Debug.LogWarning("预制体参数转换失败,请确认参数2是否是UnionResConfigData类型"); return(null); } res = GetPrefab(unionCof); break; case AssetType.Asset_FBX: res = GetFBXResource(conf); break; case AssetType.Asset_AnimationClip: res = GetAnimationClipResource(conf); break; case AssetType.Asset_AnimatorController: res = GetAnimatorControllerResource(conf); break; case AssetType.Asset_Audio: res = GetAudioResource(conf); break; case AssetType.Asset_Font: res = GetFont(conf.AssetBundleName, conf.AssetName); break; case AssetType.Asset_Material: res = GetMaterialResource(conf); break; case AssetType.Asset_Texture: res = GetTextureResource(conf); break; case AssetType.Asset_Sprite: res = GetSprite(conf.AssetBundleName, conf.AssetName); break; default: Debug.LogWarning(StringHelper.BuildString("无效的资源类型:", t)); break; } return(res); }
private static void FillUnioFileInfo(UnionResConfigData cf, ResourcePackage pkg) { if (cf == null || pkg == null) { return; } pkg.unionIndx = cf.unionIndx;; pkg.startIndex = cf.startIndex; pkg.dataLength = cf.dataLength; }
private static ResourcePackage GetResourcePackge(ResConfigData config) { ResourcePackage pkg = AllocResourcePackage(config.AssetBundleName); if (m_LoadedResourcePackage.Contains(pkg.instanceID)) { pkg.AddRef(); } else { string abName = config.AssetBundleName; string patch = AssetBundleManager.FullAssetPackagePathRoot + config.AssetBundleName; UnionResConfigData unionRes = config as UnionResConfigData; if (unionRes != null) { patch = unionRes.UnionFilePath; abName = unionRes.ShortUnionFilePath; } if (!m_RespackageTable.ContainsKey(abName)) { AssetBudleLog("AssetBundle文件不存在!,路径:" + patch); return(pkg); } RemoveNeedToUnLoadPackage(pkg.instanceID); //异步加载的列表里有他,那么要强制同步加载了 if (m_ResourcePackageRequestTable.Contains(pkg.instanceID)) { m_ResourcePackageRequestTable.Remove(pkg.instanceID); if (pkg.isUpLoadToLoadingThread) { pkg.AssetBundleInstance = pkg.fileRequest.assetBundle; } else { pkg.isUpLoadToLoadingThread = true; pkg.AssetBundleInstance = LoadAssetBundle(patch, config); } RemoveFromAssetsFileUpLoadQueue(pkg.instanceID); RemoveAssetsFileProcessingList(pkg.instanceID); PushToResourcePackageCallBackList(pkg.instanceID); } else { AssetBundle pAssetBundle = LoadAssetBundle(patch, config); pkg.AssetBundleInstance = pAssetBundle; } pkg.filePatch = patch; pkg.AddRef(); m_LoadedResourcePackage.Add(pkg.instanceID); } return(pkg); }
/// <summary> /// 相对路径 /// </summary> /// <param name="patch"></param> /// <returns></returns> public static UnionResConfigData GetUnionResConfigDataFromPatch(string path) { UnionResConfigData conf = null; AssetBundleEditorInfo info = GetAssetBundleEditorInfo(path); if (null == info) { return(conf); } conf = info.ConvertToUnionResConfigData(); return(conf); }
public UnionResConfigData ConvertToUnionResConfigData() { UnionResConfigData instance = new UnionResConfigData(); instance.AssetBundleName = FullAssetBundleName; instance.AssetName = assetName; instance.AssetGUID = guid; instance.unionIndx = -1; instance.dataLength = -1; instance.startIndex = -1; return(instance); }
private static void BuildPrefabResNode(ref ResNode result, UnionResConfigData config) { if (!isOnRunTimeMode) { BuildResNodeOnEditor <GameObject>(ref result, config); } else { BuildResNodeOnRunTime <GameObject>(ref result, config); } return; }
private static AssetBundle LoadAssetBundle(string bundleName, ResConfigData data) { if (null != data && data.GetType() == typeof(UnionResConfigData)) { UnionResConfigData unionData = data as UnionResConfigData; return(LoadAssetBundleFromFile(unionData.UnionFilePath, unionData.startIndex)); } else { return(LoadAssetBundleFromFile(bundleName)); } }
private static AssetBundleCreateRequest LoadAssetBundleAsync(string bundleName, ResConfigData data) { if (null != data && data.GetType() == typeof(UnionResConfigData)) { //return LoadAssetBundleFromMenory(bundleName, data); UnionResConfigData unionData = data as UnionResConfigData; return(LoadAssetBundleFromFileAsync(unionData.UnionFilePath, unionData.startIndex)); } else { return(LoadAssetBundleFromFileAsync(bundleName)); } }
private static ResNode GetCachePrefabResource(UnionResConfigData cof) { ResNode res = null; int InstanceID = GUIDToInstanceID(cof.AssetGUID); if (m_PrefabResCacheTable.TryGetValue(InstanceID, out res)) { res.cacheTime = 0.0f; m_PrefabResCacheTable.Remove(InstanceID); } return(res); }
/// <summary> /// 本函数不能获取预制体和字体 /// </summary> /// <param name="t"></param> /// <param name="conf"></param> /// <param name="callBack"></param> /// <param name="userDataObj"></param> /// <returns></returns> public static ResNode GetAssetsAsync(AssetType t, ResConfigData conf, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj = null, AssetLoadPriority priority = AssetLoadPriority.Priority_Normal) { ResNode res = null; if (null == conf) { return(res); } switch (t) { case AssetType.Asset_Prefab: UnionResConfigData unionCof = conf as UnionResConfigData; if (null == unionCof) { Debug.LogWarning("预制体参数转换失败,请确认参数2是否是UnionResConfigData类型"); return(null); } return(GetPrefabAsync(unionCof, callBack, userDataObj, priority)); case AssetType.Asset_FBX: return(GetFBXResourceAsync(conf, callBack, userDataObj, priority)); case AssetType.Asset_AnimationClip: return(GetAnimationClipResourceAsync(conf, callBack, userDataObj, priority)); case AssetType.Asset_AnimatorController: return(GetAnimatorControllerResourceAsync(conf, callBack, userDataObj, priority)); case AssetType.Asset_Audio: return(GetAudioResourceAsync(conf, callBack, userDataObj, priority)); case AssetType.Asset_Font: Debug.LogWarning("字体属于通用资源,不支持异步加载"); return(res); case AssetType.Asset_Material: return(GetMaterialResourceAsync(conf, callBack, userDataObj, priority)); case AssetType.Asset_Texture: return(GetTextureResourceAsync(conf, callBack, userDataObj, priority)); case AssetType.Asset_Sprite: return(GetSpriteAsync(conf.AssetBundleName, conf.AssetName, callBack, userDataObj, priority)); } Debug.LogWarning("无效的资源类型:" + t.ToString()); return(res); }
/// <summary> /// 取得预制体 /// </summary> /// <param name="assetBundeName">包名</param> /// <param name="assetName">资源名</param> /// <returns></returns> private static ResNode GetPrefab(string assetBundleName, string assetName) { Dictionary <string, UnionResConfigData> assetTable = null; if (m_PrefabConfigTable.TryGetValue(assetBundleName, out assetTable)) { UnionResConfigData cof = null; if (assetTable.TryGetValue(assetName, out cof)) { return(GetPrefab(cof)); } } Debug.LogWarning("在预制体配置中找不到:" + assetBundleName + "-" + assetName); return(null); }
/// <summary> /// 异步取得Prefab /// </summary> /// <param name="assetBundeName">包名</param> /// <param name="assetName">资源名</param> /// <returns></returns> private static ResNode GetPrefabAsync(string assetBundleName, string assetName, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj = null, AssetLoadPriority priority = AssetLoadPriority.Priority_Normal) { Dictionary <string, UnionResConfigData> assetTable = null; if (m_PrefabConfigTable.TryGetValue(assetBundleName, out assetTable)) { UnionResConfigData cof = null; if (assetTable.TryGetValue(assetName, out cof)) { return(GetPrefabAsync(cof, callBack, userDataObj, priority)); } } Debug.LogWarning("在预制体配置中找不到:" + assetBundleName + "-" + assetName); return(null); }
/// <summary> /// 计算资源回调,他们的res和cofig是一样的,只是userdataobj与回调不一样 /// </summary> /// <param name="res"></param> /// <param name="config"></param> /// <param name="callBack"></param> /// <param name="userDataObj"></param> private static void GeneratePrefabCallBack(ResNode res, UnionResConfigData config, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj) { List <AsyncLoadingObject> requestObjList = null; AsyncLoadingObject AnsycObj = BuildCallBackObj(res, config, callBack, userDataObj); if (m_PrefabRequestTable.TryGetValue(res.instanceID, out requestObjList)) { requestObjList.Add(AnsycObj); } else { requestObjList = new List <AsyncLoadingObject>(); requestObjList.Add(AnsycObj); m_PrefabRequestTable.Add(res.instanceID, requestObjList); } }
/// <summary> /// 获取资源,资源内部使用引用计数来管理资源,切勿乱调用,一个get,一个delete /// 返回的值仅仅是一个标示,没有资源~ /// </summary> /// <param name="config">资源配置</param> /// <param name="callBack">回调</param> /// <param name="userDataObj">用户数据,这个会出现在资源回调里,不需要可以填null</param> /// <param name="priority">加载优先级</param> /// <returns></returns> private static void GetPrefabResourceAsync(ref ResNode res, UnionResConfigData config, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj = null, AssetLoadPriority priority = AssetLoadPriority.Priority_Normal) { if (!isVaild) { return; } if (string.IsNullOrEmpty(config.AssetBundleName)) { return; } config.priority = priority; BuildPrefabResNodeAsync(ref res, config, callBack, userDataObj); if (res != null) { res.assetType = AssetType.Asset_Prefab; } return; }
/// <summary> /// 异步取得Prefab,返回值只是一个标示,没有资源,资源在回调中,相对于Prefabs路径 /// </summary> /// <param name="patch">路径,如:EntityPrefab/MonsterPrefab ,Skin/Hero</param> /// <returns></returns> private static ResNode GetPrefabAsync(string strParam, bool isGuid, System.Action <ResConfigData, ResNode, System.Object> callBack, System.Object userDataObj = null, AssetLoadPriority priority = AssetLoadPriority.Priority_Normal) { if (null == strParam || strParam.Equals(string.Empty)) { return(null); } if (!isGuid) { string assetName = System.IO.Path.GetFileName(strParam); string assetBundleName = System.IO.Path.GetDirectoryName(strParam).ToLower(); if (assetBundleName.Equals(string.Empty)) { assetBundleName = "default"; } assetBundleName = assetBundleName + "/" + assetName.ToLower() + "." + AssetBundleManager.PrefabVariant;; string FullAssetBundleName = "gameobject/" + assetBundleName; return(GetPrefabAsync(FullAssetBundleName, assetName, callBack, userDataObj, priority)); } else { UnionResConfigData data = null; int InstanceID = GUIDToInstanceID(strParam); if (m_PrefabGUIDConfigTable.TryGetValue(InstanceID, out data)) { return(GetPrefabAsync(data, callBack, userDataObj, priority)); } else { Debug.LogWarning("加载预制体失败,资源数据库中找不到GUID:" + strParam); } return(null); } }
/// <summary> /// 取得预制体,相对于Prefabs目录 /// </summary> /// <param name="strParam">[相对Prefabs路径,如:EntityPrefab/MonsterPrefab]</param> /// <param name="isGuid">参数是否是GUID</param> /// <returns></returns> private static ResNode GetPrefab(string strParam, bool isGuid = false) { if (null == strParam || strParam.Equals(string.Empty)) { return(null); } if (!isGuid) { string assetName = System.IO.Path.GetFileName(strParam); string assetBundleName = System.IO.Path.GetDirectoryName(strParam).ToLower(); if (assetBundleName.Equals(string.Empty)) { assetBundleName = "default"; } assetBundleName = assetBundleName + "/" + assetName.ToLower() + "." + AssetBundleManager.PrefabVariant;; string FullAssetBundleName = "gameobject/" + assetBundleName; return(GetPrefab(FullAssetBundleName, assetName)); } else { UnionResConfigData data = null; int InstanceID = GUIDToInstanceID(strParam); if (m_PrefabGUIDConfigTable.TryGetValue(InstanceID, out data)) { return(GetPrefab(data)); } else { Debug.LogWarning("加载预制体失败,资源数据库中找不到GUID:" + strParam); } return(null); } }
/// <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); }
/// <summary> /// 加载预制体配置 /// </summary> private static void LoadPrefabSelfConfig(Dictionary <string, Dictionary <string, UnionResConfigData> > result = null, Dictionary <string, PrefabDependenicesResConfigData> depedenceResult = null) { string patch = AssetBundleManager.GetPrefabConfigPath(); if (!File.Exists(patch)) { if (Application.isPlaying) { Debug.LogError("找不到预制体配置!!!-" + patch); } return; } string stSchemeAllText = DeCodeAssetFile(patch); if (stSchemeAllText.Equals(string.Empty)) { return; } if (result == null || depedenceResult == null) { result = m_PrefabConfigTable; depedenceResult = m_PrefabDependenciesConfigTable; } ////去掉\n,因为ScpReader以"\r"分割 //stSchemeAllText = stSchemeAllText.Replace("\n", ""); ////再干掉最后的"\r" //stSchemeAllText = stSchemeAllText.Remove(stSchemeAllText.Length - 1, 1); AssetBundleConfigReader PrefabReader = new AssetBundleConfigReader(stSchemeAllText, "PrefabConfig", 0); bool isNeedLoadDependenices = false; //是否需要加载依赖配置 UnionResConfigData currLoadingPrefab = null; //当前正在加载的Prefab int texcount = 0; //贴图数目 int fbxcount = 0; //fbx数目 int clipcount = 0; //clip数目 int controllercount = 0; //animatorcontroller数目 int shadercount = 0; //shader数目 int materialcount = 0; //材质球数目 string lowerPrefabCommonPatch = PrefabCommonPatch.ToLower(); for (int i = 0; i < PrefabReader.GetRecordCount(); ++i) { isNeedLoadDependenices = !(texcount == 0 && fbxcount == 0 && clipcount == 0 && controllercount == 0 && shadercount == 0 && materialcount == 0); if (!isNeedLoadDependenices) { UnionResConfigData prefabConfig = new UnionResConfigData(); prefabConfig.AssetBundleName = PrefabReader.GetString(i, (int)PrefabConfigCol.COL_AssetBundleName, string.Empty); prefabConfig.AssetName = PrefabReader.GetString(i, (int)PrefabConfigCol.COL_AssetName, string.Empty); prefabConfig.AssetGUID = PrefabReader.GetString(i, (int)PrefabConfigCol.COL_AssetGUID, string.Empty); prefabConfig.unionIndx = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_UnionIndex, -1); prefabConfig.startIndex = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_StartIndex, -1); prefabConfig.dataLength = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_DataLength, -1); if (!prefabConfig.AssetBundleName.EndsWith(PrefabVariant)) { Debug.LogWarning("预制体配置中有冗余的配置:" + prefabConfig.AssetBundleName + ",名字:" + prefabConfig.AssetName + ",重新生成资源可解决此问题 -- not gameobject"); continue; } texcount = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_TextureCount, 0); fbxcount = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_FBXCount, 0); clipcount = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_ClipCount, 0); controllercount = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_ControllerCount, 0); shadercount = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_ShaderCount, 0); materialcount = PrefabReader.GetInt(i, (int)PrefabConfigCol.COL_MaterialCount, 0); isNeedLoadDependenices = !(texcount == 0 && fbxcount == 0 && clipcount == 0 && controllercount == 0 && shadercount == 0 && materialcount == 0); if (Application.isPlaying) { if (isOnRunTimeMode) { if (prefabConfig.unionIndx < 0 || prefabConfig.startIndex < 0 || prefabConfig.dataLength <= 0) { Debug.LogWarning("无效的预制体配置中有冗余的配置:" + prefabConfig.AssetBundleName + ",名字:" + prefabConfig.AssetName + ",重新生成资源可解决此问题--uniondex < 0"); i += texcount; i += fbxcount; i += clipcount; i += controllercount; i += shadercount; i += materialcount; texcount = 0; fbxcount = 0; clipcount = 0; controllercount = 0; shadercount = 0; materialcount = 0; isNeedLoadDependenices = false; currLoadingPrefab = null; continue; } } } currLoadingPrefab = prefabConfig; int InstanceID = GUIDToInstanceID(prefabConfig.AssetGUID); if (m_PrefabGUIDConfigTable.ContainsKey(InstanceID)) { Debug.LogWarning("重复的预制体配置,GUID:" + prefabConfig.AssetGUID + "资源名:" + prefabConfig.AssetName); i += texcount; i += fbxcount; i += clipcount; i += controllercount; i += shadercount; i += materialcount; texcount = 0; fbxcount = 0; clipcount = 0; controllercount = 0; shadercount = 0; materialcount = 0; isNeedLoadDependenices = false; currLoadingPrefab = null; continue; } else { m_PrefabGUIDConfigTable.Add(InstanceID, prefabConfig); } //把预制体资源先加载进去 Dictionary <string, UnionResConfigData> assetTable = null; if (result.TryGetValue(prefabConfig.AssetBundleName, out assetTable)) { if (assetTable.ContainsKey(prefabConfig.AssetName)) { Debug.LogWarning("预制体:" + prefabConfig.AssetBundleName + "有重复的依赖资源:" + prefabConfig.AssetName); continue; } assetTable.Add(prefabConfig.AssetName, prefabConfig); } else { assetTable = new Dictionary <string, UnionResConfigData>(); assetTable.Add(prefabConfig.AssetName, prefabConfig); result.Add(prefabConfig.AssetBundleName, assetTable); //通用预制体 if (prefabConfig.AssetBundleName.Contains(lowerPrefabCommonPatch)) { PrefabCommonAssetBundleNames.Add(prefabConfig.AssetBundleName); } } //直接destroy GameObject类型的资源 //没有依赖的,给一个空配置即可 if (!isNeedLoadDependenices) { depedenceResult.Add(currLoadingPrefab.AssetGUID, new PrefabDependenicesResConfigData()); } continue; } /*开始加载配置依赖表*/ //1.先创建类 PrefabDependenicesResConfigData dependenicesConfig = null; if (!depedenceResult.TryGetValue(currLoadingPrefab.AssetGUID, out dependenicesConfig)) { dependenicesConfig = new PrefabDependenicesResConfigData(); depedenceResult.Add(currLoadingPrefab.AssetGUID, dependenicesConfig); } //先是贴图 if (texcount > 0) { texcount--; string guid = StringHelper.CopyString(PrefabReader.GetString(i, 0, string.Empty)); PushPrefabUnionRes(guid, dependenicesConfig.TextureResConfigDatas); continue; } //再加载FBX if (fbxcount > 0) { fbxcount--; string guid = StringHelper.CopyString(PrefabReader.GetString(i, 0, string.Empty)); PushPrefabUnionRes(guid, dependenicesConfig.FBXResConfigDatas); continue; } //再加载clip if (clipcount > 0) { clipcount--; string guid = StringHelper.CopyString(PrefabReader.GetString(i, 0, string.Empty)); PushPrefabUnionRes(guid, dependenicesConfig.AnimatonClipResConfigDatas); continue; } //再加载controller if (controllercount > 0) { controllercount--; string guid = StringHelper.CopyString(PrefabReader.GetString(i, 0, string.Empty)); PushPrefabUnionRes(guid, dependenicesConfig.AnimatorControllerResConfigDatas); continue; } //再加载shader if (shadercount > 0) { shadercount--; string guid = StringHelper.CopyString(PrefabReader.GetString(i, 0, string.Empty)); PushPrefabUnionRes(guid, dependenicesConfig.ShaderResConfigDatas); continue; } //再加载material if (materialcount > 0) { materialcount--; string guid = StringHelper.CopyString(PrefabReader.GetString(i, 0, string.Empty)); PushPrefabUnionRes(guid, dependenicesConfig.MaterialResConfigDatas); continue; } } PrefabReader.Dispose(); PrefabReader = null; }
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); }
/// <summary> /// 更新预制体的加载进度 /// </summary> private static void UpdatePrefabAsyncLoadingProgress() { AsyncDependenicesLoadCompleteList.Clear(); AsyncDependenicesLoadInValidList.Clear(); foreach (KeyValuePair <int, List <ResNode> > pair in m_DependenicesRequestTable) { List <ResNode> nodList = pair.Value; bool isLoadFinish = true; bool isHaveInvalidNode = false; foreach (ResNode nod in nodList) { if (!nod.isLoadFinish) { isLoadFinish = false; break; } else { if (!nod.IsValid()) { isHaveInvalidNode = true; } } } if (isLoadFinish) { AsyncDependenicesLoadCompleteList.Add(pair.Key); if (isHaveInvalidNode) { AsyncDependenicesLoadInValidList.Add(pair.Key); } } } foreach (int s in AsyncDependenicesLoadCompleteList) { m_DependenicesRequestTable[s].Clear(); m_DependenicesRequestTable[s] = null; m_DependenicesRequestTable.Remove(s); ////依赖加载完了之后,发现预制已经不需要了,直接卸载依赖 //if (m_NeedToDeletePrefab.Contains(s)) //{ // UnLoadDependenicesAsync(s); // m_NeedToDeletePrefab.Remove(s); // continue; //} List <AsyncLoadingObject> list = m_PrefabRequestTable[s]; if (m_AsyncLoadingDependicensPrefabResNode.ContainsKey(s)) { m_AsyncLoadingDependicensPrefabResNode.Remove(s); } //发现加载的依赖项有无效的资源节点,那么不进行下面的预制体本体加载 //但是,还是要进行回调,因为这个是属于加载失败. if (AsyncDependenicesLoadInValidList.Contains(s)) { m_PrefabRequestTable.Remove(s); UnLoadDependenicesAsync(s); ResNode res = AllocResNode(list[0].loadingResInstanceID); m_PrefabResTable.Add(s, res); res.status = ResNodeStatus.LoadFinish; foreach (AsyncLoadingObject obj in list) { obj.callBack(obj.configData, res, obj.UserDataObj); } list.Clear(); continue; } AsyncLoadingObject alo = list[0]; ResNode loadingResNode = AllocResNode(alo.loadingResInstanceID); UnionResConfigData config = alo.configData as UnionResConfigData; GetPrefabResourceAsync(ref loadingResNode, config, PrefabResourceCallBack, config.priority); list[0] = alo; } }
/// <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; }
private static void GetPrefabPackgeAsync(ref ResNode res, UnionResConfigData config, System.Action <ResourcePackageCallBackObj> resourcePackageCallBack, System.Action <ResConfigData, ResNode, System.Object> UserCallBack, System.Object userDataObj) { BuildPacakgeAsync(ref res, m_PrefabResTable, config, resourcePackageCallBack, UserCallBack, userDataObj, true); }
/// <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; }
public static void PushPrefabConfig(UnionResConfigData prefabConfig, List <string> TextureData, List <string> FBXData, List <string> ClipData, List <string> ControllerData, List <string> ShaderData, List <string> MaterialData) { if (null == prefabConfig) { return; } /*先添加到预制体表里去*/ Dictionary <string, UnionResConfigData> assetTable = null; UnionResConfigData cof; int InstanceID = GUIDToInstanceID(prefabConfig.AssetGUID); //如果这个预制体已经存在了,那么移除原来的预制体,再添加进去,存在多份一样的预制体信息 if (m_PrefabGUIDConfigTable.TryGetValue(InstanceID, out cof)) { //移除原来的 m_PrefabConfigTable[cof.AssetBundleName].Remove(m_PrefabGUIDConfigTable[InstanceID].AssetName); } else { m_PrefabGUIDConfigTable.Add(InstanceID, prefabConfig); } if (m_PrefabConfigTable.TryGetValue(prefabConfig.AssetBundleName, out assetTable)) { //对于已经存在的资源,则采取更新对应的资源 if (assetTable.ContainsKey(prefabConfig.AssetName)) { assetTable[prefabConfig.AssetName] = prefabConfig; } else { assetTable.Add(prefabConfig.AssetName, prefabConfig); } } else { assetTable = new Dictionary <string, UnionResConfigData>(); assetTable.Add(prefabConfig.AssetName, prefabConfig); m_PrefabConfigTable.Add(prefabConfig.AssetBundleName, assetTable); } bool isNeedToWriteDependenices = !(TextureData.Count == 0 && FBXData.Count == 0 && ClipData.Count == 0 && ControllerData.Count == 0 && ShaderData.Count == 0 && MaterialData.Count == 0); if (!isNeedToWriteDependenices) { //如果他不需要写入配置,那么检查一下原来是不是有,有的话直接移除 if (m_PrefabDependenciesConfigTable.ContainsKey(prefabConfig.AssetGUID)) { m_PrefabDependenciesConfigTable.Remove(prefabConfig.AssetGUID); } return; } //1.先创建类 PrefabDependenicesResConfigData dependenicesConfig = null; if (!m_PrefabDependenciesConfigTable.TryGetValue(prefabConfig.AssetGUID, out dependenicesConfig)) { dependenicesConfig = new PrefabDependenicesResConfigData(); m_PrefabDependenciesConfigTable.Add(prefabConfig.AssetGUID, dependenicesConfig); } else { //已经存在的,则清楚资源,更新 dependenicesConfig.TextureResConfigDatas.Clear(); dependenicesConfig.FBXResConfigDatas.Clear(); dependenicesConfig.AnimatonClipResConfigDatas.Clear(); dependenicesConfig.AnimatorControllerResConfigDatas.Clear(); dependenicesConfig.ShaderResConfigDatas.Clear(); dependenicesConfig.MaterialResConfigDatas.Clear(); } //先贴图 for (int i = 0; i < TextureData.Count; i++) { if (null != TextureData[i]) { dependenicesConfig.TextureResConfigDatas.Add(TextureData[i]); } } //再fbx for (int i = 0; i < FBXData.Count; i++) { if (null != FBXData[i]) { dependenicesConfig.FBXResConfigDatas.Add(FBXData[i]); } } //再clip for (int i = 0; i < ClipData.Count; i++) { if (null != ClipData[i]) { dependenicesConfig.AnimatonClipResConfigDatas.Add(ClipData[i]); } } //再controller for (int i = 0; i < ControllerData.Count; i++) { if (null != ControllerData[i]) { dependenicesConfig.AnimatorControllerResConfigDatas.Add(ControllerData[i]); } } //再shader for (int i = 0; i < ShaderData.Count; i++) { if (null != ShaderData[i]) { dependenicesConfig.ShaderResConfigDatas.Add(ShaderData[i]); } } //再材质球 for (int i = 0; i < MaterialData.Count; i++) { if (null != MaterialData[i]) { dependenicesConfig.MaterialResConfigDatas.Add(MaterialData[i]); } } }
private static void Export_PrefabSelfConfig(Dictionary <string, Dictionary <string, UnionResConfigData> > configTable = null, Dictionary <string, PrefabDependenicesResConfigData> depedenceResult = null) { string dic = System.IO.Path.GetDirectoryName(AssetBundleManager.GetPrefabConfigPath()); if (!System.IO.Directory.Exists(dic)) { System.IO.Directory.CreateDirectory(dic); } if (null == configTable || depedenceResult == null) { configTable = AssetBundleManager.PrefabConfigTable; depedenceResult = AssetBundleManager.PrefabDependenciesConfigTable; } StreamWriter writer = new StreamWriter(AssetBundleManager.GetPrefabConfigPath(), false, new System.Text.UTF8Encoding(true)); foreach (KeyValuePair <string, Dictionary <string, UnionResConfigData> > par in configTable) { foreach (KeyValuePair <string, UnionResConfigData> valpar in par.Value) { UnionResConfigData config = valpar.Value; //首先,取出预制的依赖配置 PrefabDependenicesResConfigData dependenicesData = null; if (!depedenceResult.TryGetValue(config.AssetGUID, out dependenicesData)) { //Debug.LogWarning("预制体:" + config.AssetName + ",没有资源依赖~"); } //先写入预制体信息,预制体信息格式为:包名,资源名,GUID,合并后的文件索引,其实位置,长度,贴图数量,FBX数量,AnimationClip数量,AnimatorController数量 string s = string.Empty; s += config.AssetBundleName; s += ","; s += config.AssetName; s += ","; s += config.AssetGUID; s += ","; s += config.unionIndx; s += ","; s += config.startIndex; s += ","; s += config.dataLength; s += ","; //这个预制体没有依赖的资源 if (null == dependenicesData) { //贴图 s += 0; s += ","; //fbx s += 0; s += ","; //clip s += 0; s += ","; //controller s += 0; s += ","; //shader s += 0; s += ","; //material s += 0; //然后就可以写入到文件了. writer.WriteLine(s); } else { s += dependenicesData.TextureResConfigDatas.Count; s += ","; s += dependenicesData.FBXResConfigDatas.Count; s += ","; s += dependenicesData.AnimatonClipResConfigDatas.Count; s += ","; s += dependenicesData.AnimatorControllerResConfigDatas.Count; s += ","; s += dependenicesData.ShaderResConfigDatas.Count; s += ","; s += dependenicesData.MaterialResConfigDatas.Count; //然后就可以写入到文件了. writer.WriteLine(s); /*写完依赖的数目之后,就可以另起一行,开始写入具体的数据*/ //先写入贴图 foreach (string cof in dependenicesData.TextureResConfigDatas) { writer.WriteLine(cof); } //再写FBX foreach (string cof in dependenicesData.FBXResConfigDatas) { writer.WriteLine(cof); } //再写clip foreach (string cof in dependenicesData.AnimatonClipResConfigDatas) { writer.WriteLine(cof); } //再写controller foreach (string cof in dependenicesData.AnimatorControllerResConfigDatas) { writer.WriteLine(cof); } //再写shader foreach (string cof in dependenicesData.ShaderResConfigDatas) { writer.WriteLine(cof); } //再写材质球 foreach (string cof in dependenicesData.MaterialResConfigDatas) { writer.WriteLine(cof); } } } } writer.Flush(); writer.Close(); }
private static void BuildPrefabWhenInAsyncLoading(ref ResNode res, UnionResConfigData config) { //先检查 if (null == res) { return; } if (!isOnRunTimeMode) { return; } if (!res.isAsync) { return; } if (res.isLoadFinish) { return; } res.StartLoadedTime(); //先从回调列表里移除 if (m_AsyncLoadingDependicensPrefabResNode.ContainsKey(res.instanceID)) { m_AsyncLoadingDependicensPrefabResNode.Remove(res.instanceID); } //卸载依赖 UnLoadDependenicesAsync(res.instanceID); //开始加载依赖 if (LoadDependenices(config)) { ResourcePackage pkg = null; pkg = GetResourcePackge(config); if (null != pkg) { LoadAssetFromAssetBundle <GameObject>(ref res, config, pkg.AssetBundleInstance); } else { AssetBudleLog("加载AssetBundle失败:" + config.AssetBundleName); } if (!res.IsValid()) { UnLoadDependenices(res.instanceID); } } else { UnLoadDependenices(res.instanceID); } res.status = ResNodeStatus.LoadFinish; m_PrefabResTable.Add(res.instanceID, res); //取出回调列表 List <AsyncLoadingObject> list = null; if (m_PrefabRequestTable.TryGetValue(res.instanceID, out list)) { ReleaseDependenicesAssetBundleIfNeed(res); ReleaseAssetBundleIfNeed(res); m_PrefabRequestTable.Remove(res.instanceID); foreach (AsyncLoadingObject obj in list) { PushToResDelayCallBackList(res, config, obj.callBack, obj.UserDataObj); } } 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); }