/// <summary> /// 加载常驻bundle /// </summary> /// <param name="complete"></param> /// <param name="progress"></param> /// <returns></returns> public IEnumerator LoadResidentBundles(Action complete = null, BundleBatchLoadingDelegate progress = null) { ResPackConfig config = ResService.GetInstance().PackConfig; if (config == null) { JW.Common.Log.LogE("In LoadResidentBundles(), but ResPackConfig is null."); if (complete != null) { complete(); } yield break; } JWObjList <BundlePackInfo> bundleList = new JWObjList <BundlePackInfo>(); for (int i = 0; i < config.PackInfo.Count; i++) { BundlePackInfo p = config.PackInfo[i] as BundlePackInfo; if (p != null && p.Life == EBundleLife.Resident) { bundleList.Add(p); } } yield return(StartCoroutine(BundleService.GetInstance().BatchLoadAsync(bundleList, complete, progress))); }
public int BundleCount(JWObjList <string> resourceList) { ResPackConfig config = ResService.GetInstance().PackConfig; if (config == null) { return(0); } JWObjList <BundlePackInfo> bundles = GetBundleList(resourceList); if (bundles == null) { return(0); } int count = 0; for (int i = 0; i < bundles.Count; i++) { // 非NoBundle资源,或者在磁盘上有这个bundle BundlePackInfo bpi = bundles[i]; //if (!bpi.IsNoBundle()) //{ // count++; //} } return(count); }
/// <summary> /// 加载bundle /// </summary> /// <param name="path">bundle路径</param> /// <param name="complete"></param> public void LoadBundle(string path, Action <string, bool> complete) { BundlePackInfo p = GetPackInfo(path); if (p == null) { if (complete != null) { complete(path, false); } return; } StartCoroutine(BundleService.GetInstance().LoadAsync(p, delegate(BundleRef bundle) { if (bundle != null && complete != null) { complete(bundle.Path, true); } }, delegate(BundlePackInfo packInfo, string error) { if (packInfo != null && complete != null) { complete(packInfo.Path, false); } }, null)); }
/// 检查是否有同名bundle存在 bool IsDuplicated(BundlePackInfo pi, out string duplicatedBundle) { duplicatedBundle = null; string name = JW.Res.FileUtil.EraseExtension(JW.Res.FileUtil.GetFullName(pi.Path)); if (string.IsNullOrEmpty(name)) { return(false); } for (int i = 0; i < _config.PackInfo.Count; i++) { BundlePackInfo p = _config.PackInfo[i] as BundlePackInfo; if (p != null) { string n = JW.Res.FileUtil.EraseExtension(JW.Res.FileUtil.GetFullName(p.Path)); if (!string.IsNullOrEmpty(n)) { if (n.Equals(name, StringComparison.OrdinalIgnoreCase)) { duplicatedBundle = p.Path; return(true); } } } } return(false); }
//根据manifest检查一遍依赖关系 private void CheckAndClearManifestFiles(BuildTarget target, bool isClear = false) { string ifsBuildDir = JW.Res.FileUtil.CombinePaths( _ifsBuildPath, GetPlatformStr(target)); // string mainAssetBundlePath = JW.Res.FileUtil.CombinePaths(ifsBuildDir, GetPlatformStr(target)); AssetBundle mainAssetBundle = AssetBundle.LoadFromFile(mainAssetBundlePath); if (mainAssetBundle == null) { Terminate("Get RootAssetBundle Failed"); return; } AssetBundleManifest mainAssetManifest = (AssetBundleManifest)mainAssetBundle.LoadAsset("AssetBundleManifest"); if (mainAssetManifest == null) { Terminate("Get RootAssetBundle Manifest Failed!"); return; } // string[] allAbs = mainAssetManifest.GetAllAssetBundles(); foreach (string ab in allAbs) { JW.Common.Log.LogD("Exist AssetBundle:" + ab); } // for (int i = 0; i < _packConfig.PackInfoAll.Count; i++) { ResPackInfo info = _packConfig.PackInfoAll[i]; if (info.GetPackType() == (byte)ResPackType.ResPackTypeBundle) { BundlePackInfo binfo = info as BundlePackInfo; //查找依賴 string[] des = mainAssetManifest.GetAllDependencies(info.Path); if (des != null && des.Length > 0) { binfo.DependencyNames = string.Join(",", des); JW.Common.Log.LogD("Add Dependency:" + binfo.DependencyNames + "-2->" + info.Path); } } } // mainAssetBundle.Unload(true); mainAssetManifest = null; // if (isClear) { string[] files = Directory.GetFiles(ifsBuildDir, "*.manifest", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { JW.Res.FileUtil.DeleteFile(files[i].Replace('\\', '/')); } //删除 Win Android IOS JW.Res.FileUtil.DeleteFile(mainAssetBundlePath); } }
/// <summary> /// unload bundle /// </summary> /// <param name="path">bundle路径</param> public void UnloadBundle(string path, bool immediately = false) { BundlePackInfo packInfo = GetPackInfo(path); if (packInfo != null) { BundleService.GetInstance().Unload(packInfo, immediately); } }
/// <summary> /// 根据资源列表取bundle列表 /// </summary> /// <param name="resourceList"></param> /// <param name="recordResources"></param> public JWObjList <BundlePackInfo> GetBundlePackInfoListForResources(JWObjList <string> resourceList, bool recordResources) { if (resourceList == null || resourceList.Count == 0) { return(null); } ResPackConfig config = ResService.GetInstance().PackConfig; if (config == null) { if (recordResources) { _unbundledResources.AddRange(resourceList); } return(null); } JWObjList <BundlePackInfo> bundleList = null; for (int i = 0; i < resourceList.Count; i++) { string path = resourceList[i]; BundlePackInfo info = config.GetPackInfoForResource(JW.Res.FileUtil.EraseExtension(path)) as BundlePackInfo; if (info != null) { if (bundleList == null) { bundleList = new JWObjList <BundlePackInfo>(); } if (!bundleList.Contains(info)) { bundleList.Add(info); } // bundle正在加载中的资源 if (recordResources && !_loadingResources.Contains(path)) { _loadingResources.Add(path); } } else { if (recordResources && !_unbundledResources.Contains(path)) { _unbundledResources.Add(path); } } } return(bundleList); }
public void InitView(BundlePackInfo info, int id) { this.id = id; this.info = info; rewardDatas = info.rewards; icon.sprite = LoadResourceController.GetBundleItemIcon(id); priceTxt.text = info.cost.ToString(); for (int i = 0; i < rewardDatas.Length; i++) { var iconView = Instantiate(LoadResourceController.GetIconView(), rewardAnchor); iconView.SetData(rewardDatas[i].GetResource()); } RefreshUI(); }
/// 生成打包参数 EPackHandlerParam GeneratePackParam(BundlePackInfo ResInfo) { EPackHandlerParam packHandlerParam = EPackHandlerParam.None; if (ResInfo.HasFlag(EBundleFlag.UnCompress)) { packHandlerParam |= EPackHandlerParam.UnCompress; } if (ResInfo.HasFlag(EBundleFlag.LZMA)) { packHandlerParam |= EPackHandlerParam.LZMA; } if (ResInfo.HasFlag(EBundleFlag.LZ4)) { packHandlerParam |= EPackHandlerParam.LZ4; } return(packHandlerParam); }
/// <summary> /// 获取预加载bundle列表 /// </summary> /// <returns></returns> public JWObjList <string> GetPreloadBundles() { JWObjList <string> bundleList = new JWObjList <string>(); ResPackConfig config = ResService.GetInstance().PackConfig; for (int i = 0; i < config.PackInfo.Count; i++) { BundlePackInfo p = config.PackInfo[i] as BundlePackInfo; if (p == null) { continue; } if (p.HasFlag(EBundleFlag.PreLoad)) { bundleList.Add(p.Path); } } return(bundleList); }
/// <summary> /// 卸载资源列表对应bundle /// </summary> /// <param name="resourcesPath"></param> public void UnloadBundle(JWObjList <string> resourcesPath) { JWObjList <BundlePackInfo> bundleList = GetBundlePackInfoListForResources(resourcesPath, false); if (bundleList != null && bundleList.Count > 0) { for (int i = 0; i < bundleList.Count; i++) { BundlePackInfo packInfo = bundleList[i]; // unity场景 if (packInfo.HasFlag(EBundleFlag.UnityScene)) { BundleService.GetInstance().OnAssetLoaded(packInfo); } else { BundleService.GetInstance().Unload(bundleList[i]); } } } }
/// <summary> /// 获取已加载的bundle对应的资源 /// </summary> /// <param name="bundlePath"></param> /// <returns></returns> public JWObjList <string> GetLoadedBundleResources(string bundlePath) { if (string.IsNullOrEmpty(bundlePath) || _loadingResources.Count == 0) { return(null); } ResPackConfig config = ResService.GetInstance().PackConfig; if (config == null) { return(null); } BundlePackInfo pi = config.GetPackInfo(bundlePath) as BundlePackInfo; if (pi == null) { return(null); } for (int i = _loadingResources.Count - 1; i >= 0; i--) { string path = _loadingResources[i]; if (pi.Contains(path)) { if (!_relatedResources.Contains(path)) { _relatedResources.Add(path); } _loadingResources.Remove(path); } } return(_relatedResources); }
JWObjList <BundlePackInfo> GetBundleList(JWObjList <string> resources) { ResPackConfig config = ResService.GetInstance().PackConfig; if (config == null) { return(null); } JWObjList <BundlePackInfo> bundles = null; for (int i = 0; i < resources.Count; i++) { string path = resources[i]; if (ResService.GetInstance().Exists(path)) { continue; } BundlePackInfo bpi = config.GetPackInfoForResource(path) as BundlePackInfo; if (bpi != null) { if (bundles == null) { bundles = new JWObjList <BundlePackInfo>(); } if (!bundles.Contains(bpi)) { bundles.Add(bpi); } } } return(bundles); }
/// 删除多余的Resource 目录资源 public void DeleteRedundantFiles(BuildTarget target) { if (_packConfig == null) { _packConfig = new ResBuildConfig(_buildCfgXML, _outCfgFileName); bool isOK = _packConfig.Parse(target, true); if (isOK == false) { _packConfig = null; Terminate("解析打包build 错误"); return; } } //TODO 去掉打包的场景 目前无用 // 删除 Action <string> Delete = (string path) => { if (string.IsNullOrEmpty(path)) { return; } // asset if (File.Exists(path)) { try { File.Delete(path); } catch (Exception e) { Terminate("Deleting assets failed, error:" + e.Message); } } // meta if (File.Exists(path + ".meta")) { try { File.Delete(path + ".meta"); } catch (Exception e) { Terminate("Deleting assets failed, error:" + e.Message); } } }; //配置定义要删除的 foreach (string asset in _packConfig.DeleteAssets) { Delete(asset); } //删除Resource 下面打包好的资源 foreach (ResPackInfo pi in _packConfig.PackInfoAll) { if (pi is BundlePackInfo) { BundlePackInfo bpi = pi as BundlePackInfo; if (bpi != null && bpi.IsNoBundle()) { continue; } } // foreach (ResInfo res in pi.Resources) { if (res.Keep) { continue; } Delete(res.RelativePath); } } }
/// 解析AssetBundle 配置节点 bool ParseBundle(XmlNode node, BuildTarget target, bool allowEmpty = true) { BundlePackInfo info = new BundlePackInfo(); // 输出文件名 info.Path = node.Attributes["DstPath"].Value; // if (node.Attributes["flags"] != null) { info.Flags = ParseResourceFlags(node.Attributes["flags"].Value); } else { //没有也需要添加如果 全局模式 if (IsGlobalBuild) { info.Flags = ParseResourceFlags(""); } } // bundle生命周期 if (node.Attributes["life"] != null) { info.Life = ParseBundleLife(node.Attributes["life"].Value); } //包里面资产配置 for (int i = 0; i < node.ChildNodes.Count; ++i) { if (node.ChildNodes[i].Name == "Asset") { bool isOK = ParseAsset(node.ChildNodes[i], info); if (isOK == false) { return(false); } } } // 没有资源 if (info.Resources.Count == 0) { if (allowEmpty || info.HasFlag(EBundleFlag.Optional)) { JW.Common.Log.LogW("No file, but ignore." + info.Path); return(true); } else { JW.Common.Log.LogW(string.Format("No asset for bundle {0}.", info.Path)); return(false); } } // 是否有同名bundle string duplicatedBundle = null; if (IsDuplicated(info, out duplicatedBundle)) { JW.Common.Log.LogE(string.Format("Bundle {0} name duplicated with {1}.", info.Path, duplicatedBundle)); return(false); } //加入配置 _config.AddPackInfo(info); return(true); }
/// 打包AssetBundle资源, void BuildBundleResource(BundlePackInfo packInfo, string ifsBuildDir, BuildTarget target) { if (packInfo == null) { return; } // 本次打包的路径和目录 string buildBundlePath = JW.Res.FileUtil.CombinePaths(ifsBuildDir, "", packInfo.Path); string buildBundleDirectory = JW.Res.FileUtil.GetFullDirectory(buildBundlePath); if (!JW.Res.FileUtil.IsDirectoryExist(buildBundleDirectory)) { JW.Res.FileUtil.CreateDirectory(buildBundleDirectory); } //========== build ========== List <string> filePathList = new List <string>(); List <string> nameList = new List <string>(); for (int j = 0; j < packInfo.Resources.Count; j++) { ResInfo res = packInfo.Resources[j]; filePathList.Add(res.RelativePath); nameList.Add(res.Path); } bool succ = false; //场景文件 if (packInfo.HasFlag(EBundleFlag.UnityScene)) { succ = ResPackHelper.BuildScene(filePathList, buildBundlePath); } else { //全局模式只是纯粹设置bundle 名称 if (_packConfig.IsGlobalBuild) { succ = ResPackHelper.JustSetBundleName(packInfo.Path, filePathList); } else { EPackHandlerParam packHandlerParam = GeneratePackParam(packInfo); succ = ResPackHelper.Build(buildBundlePath, filePathList, packHandlerParam, true, nameList); } } if (succ) { if (_packConfig.IsGlobalBuild) { JW.Common.Log.LogD("Set BundleName Success " + buildBundlePath); } else { JW.Common.Log.LogD("Build Bundle Success Out" + buildBundlePath); } } else { if (_packConfig.IsGlobalBuild) { Terminate("Set bundleName failed, path:" + buildBundlePath); } else { Terminate("Build bundle failed, path:" + buildBundlePath); } } }
/// 解析Asset配置节点 bool ParseAsset(XmlNode node, BundlePackInfo packInfo) { // source path if (node.Attributes["SrcPath"] == null || string.IsNullOrEmpty(node.Attributes["SrcPath"].Value)) { JW.Common.Log.LogE("There is no SrcPath in Asset node."); return(false); } string srcPath = node.Attributes["SrcPath"].Value; string fullPath = JW.Res.FileUtil.CombinePaths(Application.dataPath, "Resources", srcPath); string[] files = null; try { if (File.Exists(fullPath)) { //单个文件 if (node.Attributes["pattern"] != null) { Regex regex = new Regex(node.Attributes["pattern"].Value, RegexOptions.IgnoreCase); if (regex.IsMatch(fullPath)) { files = new string[1]; files[0] = fullPath; } } else { files = new string[1]; files[0] = fullPath; } } else if (Directory.Exists(JW.Res.FileUtil.GetFullDirectory(fullPath))) { //目录 SearchOption option = SearchOption.TopDirectoryOnly; if (node.Attributes["recursive"] != null && node.Attributes["recursive"].Value.ToLower() == "true") { option = SearchOption.AllDirectories; } files = Directory.GetFiles(JW.Res.FileUtil.GetFullDirectory(fullPath), JW.Res.FileUtil.GetFullName(fullPath), option).Where(name => !name.EndsWith(".meta", true, null)).ToArray(); if (node.Attributes["pattern"] != null) { Regex regex = new Regex(node.Attributes["pattern"].Value, RegexOptions.IgnoreCase); files = files.Where(f => !string.IsNullOrEmpty(f) && regex.IsMatch(f)).ToArray(); } } } catch (System.Exception e) { JW.Common.Log.LogE(string.Format("ParseAsset(), path:{0}, exception:{1}", packInfo.Path, e.Message)); return(false); } // 创建资源信息 resource info for (int j = 0; files != null && j < files.Length; j++) { string filePathInResources = GetPathInResources(files[j]); string duplicatedFile = null; if (packInfo.IsDuplicated(filePathInResources, out duplicatedFile)) { JW.Common.Log.LogE(string.Format("Duplicated resource [{0}] and [{1}] in bundle [{2}]", filePathInResources, duplicatedFile, packInfo.Path)); return(false); } ResInfo ResInfo = new ResInfo(); if (packInfo.HasFlag(EBundleFlag.UnityScene)) { ResInfo.Path = Path.GetFileNameWithoutExtension(filePathInResources); } else { ResInfo.Path = JW.Res.FileUtil.EraseExtension(filePathInResources); } int artPos = filePathInResources.IndexOf("ArtWork"); if (artPos != -1) { ResInfo.Path = ResInfo.Path.Substring(artPos + "ArtWork/".Length); ResInfo.RelativePath = JW.Res.FileUtil.CombinePath("Assets", filePathInResources.Substring(artPos)); } else { ResInfo.RelativePath = JW.Res.FileUtil.CombinePath("Assets/Resources", filePathInResources); } //扩展名 ResInfo.Ext = JW.Res.FileUtil.GetExtension(filePathInResources); //是否保持 if (node.Attributes["keep"] != null && node.Attributes["keep"].Value.Equals("true", StringComparison.OrdinalIgnoreCase)) { ResInfo.Keep = true; } else { ResInfo.Keep = false; } packInfo.Add(ref ResInfo); } return(true); }
void OnGUI() { if (!BundleService.IsValidate()) { return; } JWObjDictionary <string, BundleRef> bundleDict = BundleService.GetInstance().BundleDict; GUILayout.Space(3f); GUILayout.BeginVertical(); // list title GUILayout.BeginHorizontal("Table Title", GUILayout.MinHeight(20f)); GUILayout.Label("Index", _labelStyle, GUILayout.Width(60f)); GUILayout.Label("RefCnt", _labelStyle, GUILayout.Width(60f)); GUILayout.Label("Tag", _labelStyle, GUILayout.Width(120f)); GUILayout.Label("Name", _labelStyle, GUILayout.Width(60f)); GUILayout.EndHorizontal(); ResPackConfig config = ResService.GetInstance().PackConfig; if (config == null) { return; } // list mScroll = GUILayout.BeginScrollView(mScroll); int index = 0; foreach (var kv in bundleDict) { BundleRef bundle = kv.Value; BundlePackInfo pi = config.GetPackInfo(bundle.Path) as BundlePackInfo; if (pi == null) { continue; } index++; GUILayout.BeginHorizontal("Table Row", GUILayout.MinHeight(20f)); // index GUILayout.Label(index.ToString(), _labelStyle, GUILayout.Width(60f)); // ref count GUILayout.Label(bundle.RefCnt.ToString(), _labelStyle, GUILayout.Width(60f)); // tag //GUILayout.Label(pi.Tag, _labelStyle, GUILayout.Width(120f)); // path GUILayout.Label(pi.Path, _labelStyle); GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.Space(3f); }