/// <summary> /// 设置资源的AB名称 /// </summary> private void SetAbName() { string savePath = BuilderPreference.BUILD_PATH + "/tempsizefile.txt"; if (File.Exists(savePath)) { File.Delete(savePath); } AssetDatabase.Refresh(); // 设置ab名 AssetBuildRule[] rules = AssetBuildRuleManager.Instance.Rules; Builder.AddBuildLog("<Assetbundle Building> Start set AssetBundleName..."); Dictionary <string, List <AssetBuildRule> > path2ruleMap = new Dictionary <string, List <AssetBuildRule> >(); for (int i = 0; i < rules.Length; i++) { List <AssetBuildRule> ruleList = rules[i].TreeToList(); for (int j = 0; j < ruleList.Count; j++) { AssetBuildRule rule = ruleList[j]; List <AssetBuildRule> pathRules = null; if (!path2ruleMap.TryGetValue(rule.Path, out pathRules)) { pathRules = new List <AssetBuildRule>(); path2ruleMap[rule.Path] = pathRules; } pathRules.Add(rule); } } //获取根目录下的所有文件 List <string> files = new List <string>(); for (int i = 0; i < rules.Length; i++) { List <string> rootFiles = BuildUtil.SearchFiles(rules[i], path2ruleMap); if (rootFiles != null) { files.AddRange(rootFiles); } } Builder.AssetMaps = new Dictionary <string, AssetMap>(); Dictionary <string, AssetMap> assetMaps = Builder.AssetMaps; //构建映射关系 for (int i = 0; i < files.Count; i++) { AssetMap fileAssetMap = null; FileType fileType = BuildUtil.GetFileType(new FileInfo(files[i])); if (!assetMaps.TryGetValue(files[i], out fileAssetMap)) { AssetBuildRule rule = findRuleByPath(files[i], path2ruleMap, fileType); if (rule == null) { Debug.LogError("Cant find bundle rule!" + files[i]); } fileAssetMap = new AssetMap(files[i], rule); assetMaps[files[i]] = fileAssetMap; } fileAssetMap.IsBinding = true; //显示设置bundle规则的文件 //被忽略的规则不查找依赖 if (fileAssetMap.Rule.BuildType == (int)BundleBuildType.Ignore) { continue; } string[] dependency = AssetDatabase.GetDependencies(files[i]); for (int j = 0; j < dependency.Length; j++) { string relativePath = BuildUtil.Replace(dependency[j]); string extension = Path.GetExtension(dependency[j]); if (BuilderPreference.ExcludeFiles.Contains(extension) || relativePath.Equals(files[i])) { continue; } AssetMap assetMap = null; FileType depFileType = BuildUtil.GetFileType(new FileInfo(relativePath)); if (!assetMaps.TryGetValue(relativePath, out assetMap)) { AssetBuildRule rule = findRuleByPath(relativePath, path2ruleMap, depFileType); rule = rule == null ? fileAssetMap.Rule : rule; assetMap = new AssetMap(relativePath, rule); assetMaps[relativePath] = assetMap; } assetMap.AddReference(fileAssetMap); fileAssetMap.AddDependency(assetMap); } } //根据明确的子目录设置AB名,即定义了指定的打包规则的目录 foreach (AssetMap asset in assetMaps.Values) { if (asset.Rule.BuildType == (int)BundleBuildType.Ignore || !asset.IsBinding) { continue; } // Builder.AddBuildLog(string.Format("set assetbundle name , path {0} : {1}", asset.AssetPath, asset.Rule.AssetBundleName)); BuildUtil.SetAssetbundleName(asset.AssetPath, asset.Rule); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Builder.AddBuildLog("<Assetbundle Building> set assetbundle name ... end"); //设置依赖文件的Assetbundle分配 this.checkDependency(assetMaps); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Builder.AddBuildLog("<Assetbundle Building> Check Dependency... end"); }
public void AddChildrenRecursive(string path, AssetElement item, IList <AssetElement> rows, bool checkHave = false) { DirectoryInfo folder = new DirectoryInfo(path); if (!folder.Exists) { return; } FileSystemInfo[] files = folder.GetFileSystemInfos(); int length = files.Length; string[] includeExtensions = BuildUtil.GetFileExtension(item.BuildRule.FileFilterType); HashSet <string> includeSet = new HashSet <string>(); if (includeExtensions != null) { for (int i = 0; i < includeExtensions.Length; i++) { includeSet.Add(includeExtensions[i]); } } HashSet <string> includes = new HashSet <string>(); for (int i = 0; i < length; ++i) { //隐藏文件 if ((files[i].Attributes & FileAttributes.Hidden) == FileAttributes.Hidden || files[i].Name.EndsWith(".meta"))//&& (files[i].Attributes & FileAttributes.System) != FileAttributes.System) { continue; } string extension = Path.GetExtension(files[i].Name); if (!string.IsNullOrEmpty(extension) && !includeSet.Contains(extension)) { continue; } AssetElement childItem = null; if (checkHave) { string guid = AssetDatabase.AssetPathToGUID(BuildUtil.RelativePaths(files[i].FullName)); childItem = FindGuid(guid); if (childItem == null) { childItem = CreateTreeViewItemForGameObject(files[i], item, i); if (rows.Count > index) { rows.Insert(index, childItem); } else { rows.Add(childItem); } } } else { childItem = CreateTreeViewItemForGameObject(files[i], item, i); rows.Add(childItem); //AddChildrenRecursive(files[i].FullName, childItem, rows, checkHave); } childItem.Reflush(); includes.Add(childItem.GUID); //Debug.LogError(rows.Count + "====" + index + "===" + files[i].Name); } //删除旧数据 if (item.children != null && item.children.Count != includes.Count) { for (int i = item.children.Count - 1; i >= 0; i--) { TreeElement element = item.children[i]; if (!includes.Contains(element.GUID)) { item.children.RemoveAt(i); m_Data.Remove(element as AssetElement); } } } }
/// <summary> /// 压缩StreamAsset目录的资源 /// </summary> /// <param name="maxFileSize"></param> protected void CompressWithZSTD(long maxFileSize) { string outPutPath = BuilderPreference.StreamingAssetsPlatormPath; var dirInfo = new DirectoryInfo(outPutPath); var dirs = dirInfo.GetDirectories(); Dictionary <int, List <string> > allFiles = new Dictionary <int, List <string> >(); // data原始包控制在10M左右 long curSize = 0; int tmpIndex = 0; for (int i = 0; i < dirs.Length; ++i) { if (dirs[i].Name == "lua") { continue; } var abFileInfos = BuildUtil.SearchFiles(dirs[i].FullName, SearchOption.AllDirectories); for (int j = 0; j < abFileInfos.Count; ++j) { var relativePath = abFileInfos[j]; var data = new FileInfo(relativePath); if (data.Length >= maxFileSize) { curSize = 0; tmpIndex++; } else if (curSize >= maxFileSize) { curSize = 0; tmpIndex++; } if (curSize == 0) { allFiles.Add(tmpIndex, new List <string>()); } allFiles[tmpIndex].Add(relativePath); curSize += data.Length; } } // 合并生成的bundle文件,合成10M左右的小包(二进制) Builder.AddBuildLog("<Copresss zstd> merge and compress with zstd..."); compressIndex = 0; compressCount = allFiles.Count; foreach (var key in allFiles.Keys) { var tmpName = "data" + key; #if UNITY_IOS tmpName = IOSGenerateHelper.RenameResFileWithRandomCode(tmpName); #endif var savePath = string.Format("{0}/{1}.tmp", outPutPath, tmpName); List <string> mergePaths = allFiles[key]; ThreadPool.QueueUserWorkItem(onThreadCompress, new object[] { savePath, outPutPath, mergePaths }); } }
/// <summary> /// 特殊处理主角相关的贴图 /// </summary> /// <summary> /// 特殊处理主角相关的贴图 /// </summary> private void PackPlayerModelTexture() { // 删除与主角合并Texture相关的AB string bundlePath = BuilderPreference.BUILD_PATH; string[] tempFiles = Directory.GetDirectories(bundlePath, "*", SearchOption.AllDirectories) .Where(f => f.Contains("_tmp")).ToArray(); Builder.AddBuildLog("<Assetbundle Building> delete tmp assets ..." + tempFiles.Length); for (int i = 0; i < tempFiles.Length; i++) { string dirPath = BuildUtil.Replace(tempFiles[i]); Directory.Delete(dirPath, true); string relativePath = BuildUtil.RelativePaths(tempFiles[i]); File.Delete(relativePath + ".meta"); } //合并贴图 string root = "Assets/Models/RoleModels/"; string[] subFolder = new string[3] { "Players", "Weapons", "Wings" }; Dictionary <string, List <string> > textureDict = new Dictionary <string, List <string> >(); Builder.AddBuildLog("<Assetbundle Building> Get model texture map..."); for (int i = 0; i < subFolder.Length; ++i) { string path = root + subFolder[i]; List <string> files = new List <string>(); string[] jpgs = Directory.GetFiles(path, "*.jpg", SearchOption.AllDirectories); files.AddRange(jpgs); string[] pngs = Directory.GetFiles(path, "*.png", SearchOption.AllDirectories); files.AddRange(pngs); for (int j = 0; j < files.Count; ++j) { var file = files[j].Replace("\\", "/").ToLower(); string id = Path.GetFileNameWithoutExtension(file).Replace("_light", ""); List <string> lists; if (!textureDict.TryGetValue(id, out lists)) { lists = new List <string>(); lists.Add(file); textureDict.Add(id, lists); } else { if (file.EndsWith(".png")) { lists.Insert(0, file); } else { lists.Add(file); } } } } string save_path = Path.Combine(BuilderPreference.BUILD_PATH, "/combinedtextures"); BuildUtil.SwapDirectory(save_path); int index = 0; Builder.AddBuildLog("<Assetbundle Building> Pack Model Texture..."); foreach (string fileName in textureDict.Keys) { List <string> files = textureDict[fileName]; if (fileName.Contains("_normal", StringComparison.OrdinalIgnoreCase)) { for (int i = 0; i < files.Count; ++i) { if (files[i].Contains("/Players/")) { if (File.Exists(files[i])) { File.Delete(fileName); break; } } } } if (files.Count < 2) { continue; } var file_path = string.Concat(save_path, "/", fileName, ".bytes").ToLower(); var pngBytes = File.ReadAllBytes(files[0]); var jpgBytes = File.ReadAllBytes(files[1]); using (var fs = new FileStream(file_path, FileMode.OpenOrCreate)) { byte[] intPngBuff = BitConverter.GetBytes(pngBytes.Length); fs.Write(intPngBuff, 0, 4); fs.Write(pngBytes, 0, pngBytes.Length); byte[] intJpgBuff = BitConverter.GetBytes(jpgBytes.Length); fs.Write(intJpgBuff, 0, 4); fs.Write(jpgBytes, 0, jpgBytes.Length); fs.Flush(); } index++; } //end foreach }
public void Reflush() { AssetElement parentAssetItem = parent as AssetElement; if (parentAssetItem.BuildRule.BuildType == (int)BundleBuildType.Ignore) //ignore { BuildRule.Order = -1; BuildRule.BuildType = (int)BundleBuildType.Ignore; return; } if (this.FileType != FileType.Folder) { if ((parentAssetItem.BuildRule.BuildType & (int)BundleBuildType.TogetherFiles) != 0) { BuildRule.AssetBundleName = parentAssetItem.BuildRule.AssetBundleName; BuildRule.Order = parentAssetItem.BuildRule.Order; BuildRule.DownloadOrder = parentAssetItem.BuildRule.DownloadOrder; BuildRule.BuildType = (int)BundleBuildType.TogetherFiles; return; } } else if (this.FileType == FileType.Folder) { if ((parentAssetItem.BuildRule.BuildType & (int)BundleBuildType.TogetherFolders) != 0) { BuildRule.AssetBundleName = parentAssetItem.BuildRule.AssetBundleName; BuildRule.Order = parentAssetItem.BuildRule.Order; BuildRule.DownloadOrder = parentAssetItem.BuildRule.DownloadOrder; BuildRule.BuildType = (int)(BundleBuildType.TogetherFolders | BundleBuildType.TogetherFiles); return; } } //bundle name string curBundleName = Path.GetFileNameWithoutExtension(BuildRule.AssetBundleName); string parentBundleName = parentAssetItem.BuildRule.AssetBundleName; if (!string.IsNullOrEmpty(parentBundleName)) { if (!fileName.Equals(curBundleName) && !parentAssetItem.name.Equals(curBundleName)) { BuildRule.AssetBundleName = string.Concat(parentBundleName, "/", curBundleName); } else { BuildRule.AssetBundleName = string.Concat(parentBundleName, "/", fileName); } } //打包顺序 int offsetOrder = this.BuildRule.Order % 1000; if (BuildRule.FileFilterType == FileType.Folder) { //未设置的情况 BuildRule.FileFilterType = parentAssetItem.BuildRule.FileFilterType; } BuildRule.Order = BuildUtil.GetFileOrder(BuildRule.FileFilterType) + offsetOrder; if (BuildRule.BuildType == (int)BundleBuildType.Ignore) { BuildRule.Order = -1; } // BuildRule.BuildType = (int)BundleBuildType.Separate; //下载顺序 todo }
protected string BuildApp(bool packAllRes, bool forceUpdate) { Builder.AddBuildLog("Build App Start !... packAllRes:" + packAllRes + ",force update:" + forceUpdate); var option = BuildOptions.None; if (Builder.IsDebug) { option |= BuildOptions.AllowDebugging; } if (Builder.IsBuildDev) { option |= BuildOptions.Development; } if (Builder.IsAutoConnectProfile) { option |= BuildOptions.ConnectWithProfiler; } string dir = Path.GetDirectoryName(Builder.ApkSavePath); string fileName = Path.GetFileNameWithoutExtension(Builder.ApkSavePath); string time = DateTime.Now.ToString("yyyyMMdd"); string flag = string.Empty; BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget; string final_path = string.Empty; if (buildTarget != BuildTarget.iOS) { SDKConfig curSdkConfig = Builder.CurrentConfigSDK; for (int i = 0; i < curSdkConfig.items.Count; i++) { var item = Builder.CurrentConfigSDK.items[i]; BuildOptions targetOptions = option; if (item.development == 1) { targetOptions |= BuildOptions.Development; flag = packAllRes ? "_allpack_dev_v" : "_subpack_dev_v"; } else if (item.use_sdk == 1) { flag = packAllRes ? "_allpack_sdk_v" : "_subpack_sdk_v"; } else { flag = packAllRes ? "_allpack_test_v" : "_subpack_test_v"; } if (buildTarget == BuildTarget.Android) { final_path = string.Concat(dir, "/", fileName, "_", time, flag, Builder.GameVersion.ToString(), ".apk"); if (File.Exists(final_path)) { File.Delete(final_path); } // 写入并保存sdk启用配置 // item.CopyConfig(); // item.CopySDK(); // item.SetPlayerSetting(curSdkConfig.splash_image); // item.SaveSDKConfig(); //item.SplitAssets(sdkConfig.split_assets); if (item.update_along == 0 && forceUpdate) { if (Directory.Exists(Application.streamingAssetsPath)) { Directory.Delete(Application.streamingAssetsPath, true); } } } else if (buildTarget == BuildTarget.StandaloneWindows64 || buildTarget == BuildTarget.StandaloneWindows) { final_path = string.Concat(dir, "/", fileName, "_", time, flag, Builder.GameVersion.ToString(), ".exe"); if (Directory.Exists(final_path)) { Directory.Delete(final_path, true); } item.CopyConfig(); } AssetDatabase.Refresh(); BuildUtil.SwapPathDirectory(final_path); BuildPipeline.BuildPlayer(GetBuildScenes(), final_path, buildTarget, targetOptions); item.ClearSDK(); } } else if (buildTarget == BuildTarget.iOS) { // 在上传目录新建一个ios_check.txt文件用于判断当前包是否出于提审状态 string checkFile = BuilderPreference.ASSET_PATH + "/ios_check.txt"; if (File.Exists(checkFile)) { File.Delete(checkFile); } File.WriteAllText(checkFile, "1"); XCConfigItem configItem = XCConfigItem.ParseXCConfig(XCodePostProcess.config_path); if (configItem != null) { PlayerSettings.applicationIdentifier = configItem.bundleIdentifier; PlayerSettings.productName = configItem.product_name; configItem.CopyConfig(); } // IOSGenerateHelper.IOSConfusing(); AssetDatabase.Refresh(); BuildPipeline.BuildPlayer(GetBuildScenes(), Builder.ApkSavePath, buildTarget, option); } Resources.UnloadUnusedAssets(); GC.Collect(); Builder.AddBuildLog("[end]Build App Finish !..."); return(final_path); }
private void drawRightCenterGUI() { GUILayoutOption largeButtonWidth = GUILayout.MaxWidth(120); GUILayoutOption nomaleButtonWidth = GUILayout.MaxWidth(80); GUILayoutOption miniButtonWidth = GUILayout.MaxWidth(30); m_SearchField.OnGUI(searchbarRect, ""); GUILayout.Space(30); GUILayout.BeginHorizontal(); if (GUILayout.Button("Options:", nomaleButtonWidth)) { treeView.Toggle = !treeView.Toggle; } if (GUILayout.Button(iconReflush, miniButtonWidth)) { treeModel.AddChildrens(treeView.GetSelection()); } GUILayout.FlexibleSpace(); if (GUILayout.Button("Clear All AB", GUI.skin.button, largeButtonWidth)) { BuildUtil.ClearAssetBundleName(); AssetDatabase.Refresh(); } GUILayout.Space(20); GUILayout.EndHorizontal(); Rect treeViewRect = multiColumnTreeViewRect; this.treeView.OnGUI(treeViewRect); GUILayout.Space(treeViewRect.height + 10); GUILayout.BeginHorizontal(); if (GUILayout.Button(">>", miniButtonWidth)) { treeView.ExpandAll(); } if (GUILayout.Button("+", GUI.skin.button, miniButtonWidth)) { this.addNewRootFolder(); } if (GUILayout.Button("-", GUI.skin.button, miniButtonWidth)) { this.treeModel.RemoveSelectElement(); } if (GUILayout.Button("<<", miniButtonWidth)) { treeView.CollapseAll(); } GUILayout.FlexibleSpace(); if (GUILayout.Button("Save", GUI.skin.button, nomaleButtonWidth)) { treeModel.Save(); } GUILayout.Space(20); GUILayout.EndHorizontal(); }
void CellGUI(Rect cellRect, TreeViewItem <AssetElement> item, AssetTreeHeader column, ref RowGUIArgs args) { // Center cell rect vertically (makes it easier to place controls, icons etc in the cells) CenterRectUsingSingleLineHeight(ref cellRect); AssetElement element = item.data; AssetBuildRule buildRule = element.BuildRule; switch (column) { case AssetTreeHeader.Icon: { // EditorGUI.BeginDisabledGroup(!item.data.IsBuild); if (buildRule.BuildType == 0) { GUI.DrawTexture(cellRect, iconIgnore, ScaleMode.ScaleToFit); } else { GUI.DrawTexture(cellRect, icons[GetIconByIndex(item)], ScaleMode.ScaleToFit); } // EditorGUI.EndDisabledGroup(); } break; //case MyColumns.Icon2: // { // GUI.DrawTexture(cellRect, s_TestIcons[GetIcon2Index(item)], ScaleMode.ScaleToFit); // } // break; case AssetTreeHeader.AssetName: { if (!Toggle) { args.rowRect = cellRect; base.RowGUI(args); } else { // Do toggle Rect toggleRect = cellRect; toggleRect.x += GetContentIndent(item); toggleRect.width = kToggleWidth; if (toggleRect.xMax < cellRect.xMax) { // EditorGUI.BeginDisabledGroup(false); bool beforeToggle = item.data.Toggle; // item.data.IsBuild = EditorGUI.Toggle(toggleRect, item.data.IsBuild); // hide when outside cell rect item.data.Toggle = EditorGUI.Toggle(toggleRect, item.data.Toggle); if (item.data.Toggle != beforeToggle) { // if (element.FileType == FileType.Folder) // { // if (item.data.Before != item.data.IsBuild) // { if (item.data.children != null) { for (int i = 0; i < item.data.children.Count; i++) { item.data.children[i].Toggle = item.data.Toggle; } } // } // item.data.Before = item.data.IsBuild; // } } // EditorGUI.EndDisabledGroup(); } // EditorGUI.BeginDisabledGroup(false);//!item.data.IsBuild // Default icon and label args.rowRect = cellRect; base.RowGUI(args); // EditorGUI.EndDisabledGroup(); } } break; case AssetTreeHeader.NameAB: buildRule.AssetBundleName = EditorGUI.TextField(cellRect, buildRule.AssetBundleName); // break; case AssetTreeHeader.Order: int newOrder = EditorGUI.IntField(cellRect, buildRule.Order); if (newOrder != buildRule.Order) { buildRule.Order = Math.Min(newOrder, BuildUtil.GetFileOrder(buildRule.FileFilterType) + 999); } break; case AssetTreeHeader.File: if (element.FileType == FileType.Folder) { FileType fileFilterType = (FileType)EditorGUI.EnumPopup(cellRect, buildRule.FileFilterType); if (fileFilterType != buildRule.FileFilterType) { buildRule.FileFilterType = fileFilterType; buildRule.Order = BuildUtil.GetFileOrder(fileFilterType); //刷新子结点 assetTreeModel.AddChildrens(new [] { element.id }); } } else { EditorGUI.LabelField(cellRect, buildRule.FileFilterType.ToString()); } break; case AssetTreeHeader.Build: drawHeaderBuildType(element, cellRect, buildRule); break; // case AssetTreeHeader.Ignore: // buildRule.BuildType = (PackageAssetType)EditorGUI.EnumPopup(cellRect, buildRule.BuildType); // break; } }
private void drawLeftCenterGUI() { EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); GUILayout.Toggle(false, "Configs", EditorStyles.toolbarButton); EditorGUILayout.EndHorizontal(); GUILayout.Space(5); GUILayout.BeginHorizontal(); GUILayout.Label("Asset Version", GUILayout.MaxWidth(100)); GUI.color = Color.gray; GUILayout.TextField(mainBuilder.GameVersion.ToString()); GUI.color = Color.white; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("App Version", GUILayout.MaxWidth(100)); GUI.color = Color.gray; GUILayout.TextField(mainBuilder.ApkVersion.ToString()); GUI.color = Color.white; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("SDK Config", GUILayout.Width(100))) { BuildUtil.DisableCacheServer(); Debug.Log("编辑打开!!!!"); } GUI.backgroundColor = Color.red; sdkConfigIndex = EditorGUILayout.Popup(sdkConfigIndex, mainBuilder.NameSDKs, GUILayout.MaxWidth(160)); GUI.backgroundColor = Color.white; GUILayout.EndHorizontal(); GUILayout.Space(10); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Development Build", mainBuilder.IsBuildDev ? EditorStyles.boldLabel : EditorStyles.label, GUILayout.MaxWidth(160)); mainBuilder.IsBuildDev = EditorGUILayout.Toggle(mainBuilder.IsBuildDev, GUILayout.MaxWidth(30)); GUILayout.EndHorizontal(); if (!this.mainBuilder.IsBuildDev) { this.mainBuilder.IsAutoConnectProfile = false; this.mainBuilder.IsScriptDebug = false; } EditorGUI.BeginDisabledGroup(!this.mainBuilder.IsBuildDev); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Script Debugging", this.mainBuilder.IsScriptDebug ? EditorStyles.boldLabel : EditorStyles.label, GUILayout.MaxWidth(160)); this.mainBuilder.IsScriptDebug = EditorGUILayout.Toggle(this.mainBuilder.IsScriptDebug, GUILayout.MaxWidth(30)); GUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Autoconnect Profile", this.mainBuilder.IsAutoConnectProfile ? EditorStyles.boldLabel : EditorStyles.label, GUILayout.MaxWidth(160)); this.mainBuilder.IsAutoConnectProfile = EditorGUILayout.Toggle(this.mainBuilder.IsAutoConnectProfile, GUILayout.MaxWidth(30)); GUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); // EditorGUILayout.BeginHorizontal(); // EditorGUILayout.LabelField("Config Table", GUILayout.MaxWidth(160)); // this.mainBuilder.IsDebug = EditorGUILayout.Toggle(this.mainBuilder.IsDebug, GUILayout.MaxWidth(30)); // GUILayout.EndHorizontal(); // // EditorGUILayout.BeginHorizontal(); // EditorGUILayout.LabelField("Lua Script", GUILayout.MaxWidth(160)); // this.mainBuilder.IsDebug = EditorGUILayout.Toggle(this.mainBuilder.IsDebug, GUILayout.MaxWidth(30)); // GUILayout.EndHorizontal(); GUILayout.Space(10); GUI.backgroundColor = Color.yellow; if (GUILayout.Button("Debug Build")) { mainBuilder.OnClickDebugBuild(true); } GUI.backgroundColor = Color.white; GUILayout.Space(10); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Buildings", GUILayout.Width(100)); buildingIndex = EditorGUILayout.Popup(buildingIndex, styles.BuildContents); GUILayout.EndHorizontal(); if (GUILayout.Button("Build")) { int packageBuildins = styles.BuildPackageOpts[buildingIndex]; if ((packageBuildins & (int)PackageBuildings.BuildApp) != 0) { string rootPath = Path.GetFullPath(Path.Combine(Application.dataPath, "../")); string filePath = EditorUtility.SaveFilePanel("Tip", rootPath, PlayerSettings.productName, BuilderPreference.AppExtension.Substring(1)); if (!string.IsNullOrEmpty(filePath)) { mainBuilder.ApkSavePath = filePath; mainBuilder.OnClickBuild(styles.BuildingOpts[buildingIndex], packageBuildins); } } else { mainBuilder.OnClickBuild(styles.BuildingOpts[buildingIndex], packageBuildins); } } GUILayout.Space(10); //GUILayout.Label("", "IN Title"); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Auto Build", GUILayout.Width(100)); autoBuildIndex = EditorGUILayout.Popup(autoBuildIndex, styles.OnekeyBuilds); GUILayout.EndHorizontal(); GUI.backgroundColor = Color.green; if (GUILayout.Button("Go")) { string rootPath = Path.GetFullPath(Path.Combine(Application.dataPath, "../")); string filePath = EditorUtility.SaveFilePanel("Tip", rootPath, PlayerSettings.productName, BuilderPreference.AppExtension.Substring(1)); if (!string.IsNullOrEmpty(filePath)) { mainBuilder.OnClickAutoBuild(filePath, styles.AutoBuilds[autoBuildIndex]); } } GUI.backgroundColor = Color.white; GUILayout.Space(5); GUILayout.Label("", "IN Title"); GUILayout.Space(-5); GUILayout.BeginVertical(GUILayout.MaxHeight(this.Position.height * 0.5f)); drawBundleRulePropertys(); GUILayout.EndVertical(); }
/// <summary> /// 复制分包资源到StreamingAssets目录下 /// </summary> void CopyPackableFiles() { string targetPath = BuilderPreference.StreamingAssetsPlatormPath; if (Directory.Exists(targetPath)) { Directory.Delete(targetPath, true); } Directory.CreateDirectory(targetPath); string bundlePath = BuilderPreference.BUILD_PATH; //拷贝StreamAsset目录中的资源 AssetBuildRule[] rules = AssetBuildRuleManager.Instance.Rules; Dictionary <string, AssetBuildRule> ruleMap = new Dictionary <string, AssetBuildRule>(); for (int i = 0; i < rules.Length; i++) { List <AssetBuildRule> ruleList = rules[i].TreeToList(); for (int j = 0; j < ruleList.Count; j++) { ruleMap[ruleList[j].AssetBundleName] = ruleList[j]; } } //只拷贝整包类型的文件 foreach (AssetBuildRule bundleRule in ruleMap.Values) { if (bundleRule.PackageType != PackageAssetType.InPackage) { continue; } string assetBundleName = BuildUtil.FormatBundleName(bundleRule); string buildBundlePath = string.Concat(bundlePath, "/", assetBundleName, BuilderPreference.VARIANT_V1); if (!File.Exists(buildBundlePath)) { continue; } string streamBundlePath = string.Concat(targetPath, "/", assetBundleName, BuilderPreference.VARIANT_V1); BuildUtil.SwapPathDirectory(streamBundlePath); File.Copy(buildBundlePath, streamBundlePath); } Action <List <string>, string> copyFiles = (filePaths, rootPath) => { for (int i = 0; i < filePaths.Count; i++) { string relativePath = filePaths[i]; if (!File.Exists(relativePath)) { continue; } string streamBundlePath = relativePath.Replace(rootPath, targetPath); BuildUtil.SwapPathDirectory(streamBundlePath); File.Copy(relativePath, streamBundlePath); } }; HashSet <string> includeExtensions = new HashSet <string>() { ".ab", ".unity3d", ".txt", ".conf", ".pb", ".bytes" }; //拷贝bundle配置目录的配置文件 string[] copyTargetPaths = new[] { string.Concat(bundlePath, "/files.txt"), string.Concat(bundlePath, "/bundlemap.ab"), string.Concat(bundlePath, "/font.ab"), string.Concat(bundlePath, "/shader.ab"), }; List <string> files = new List <string>(copyTargetPaths); copyFiles(files, bundlePath); //拷贝Lua目录代码 string luaBundlePath = string.Concat(bundlePath, "/lua"); files = BuildUtil.SearchIncludeFiles(luaBundlePath, SearchOption.AllDirectories, includeExtensions); copyFiles(files, luaBundlePath); Builder.AddBuildLog("<Sub Package Building>Copy sub package files ..."); AssetDatabase.Refresh(); }
private void BuildFileIndex() { Builder.AddBuildLog("<Asset Config Building> start Build File Index ...."); string resPath = BuilderPreference.BUILD_PATH + "/"; //----------------------创建文件列表----------------------- string newFilePath = resPath + "files.txt"; if (File.Exists(newFilePath)) { File.Delete(newFilePath); } string tempSizeFile = resPath + "tempsizefile.txt"; Dictionary <string, string> assetTypeDict = new Dictionary <string, string>(); if (File.Exists(tempSizeFile)) { var sizeFileContent = File.ReadAllText(tempSizeFile); var temps = sizeFileContent.Split('\n'); for (int i = 0; i < temps.Length; ++i) { if (!string.IsNullOrEmpty(temps[i])) { var temp = temps[i].Split('|'); if (temp.Length != 2 && temp.Length != 3) { throw new System.IndexOutOfRangeException(); } var assetType = temp[1]; if (temp.Length == 3) { assetType += "|" + temp[2]; } assetTypeDict.Add(temp[0], assetType); //UpdateProgress(i, temps.Length, temps[i]); } } // EditorUtility.ClearProgressBar(); } List <string> includeFiles = BuildUtil.SearchFiles(resPath, SearchOption.AllDirectories); HashSet <string> excludeSuffxs = new HashSet <string>() { ".DS_Store", ".manifest" }; //排除文件 BuildUtil.SwapPathDirectory(newFilePath); using (FileStream fs = new FileStream(newFilePath, FileMode.CreateNew)) { StreamWriter sw = new StreamWriter(fs); for (int i = 0; i < includeFiles.Count; i++) { string file = includeFiles[i]; string ext = Path.GetExtension(file); if (excludeSuffxs.Contains(ext) || file.EndsWith("apk_version.txt") || file.Contains("tempsizefile.txt") || file.Contains("luamd5.txt")) { continue; } string md5 = MD5.ComputeHashString(file); int size = (int)new FileInfo(file).Length; string value = file.Replace(resPath, string.Empty).ToLower(); if (assetTypeDict.ContainsKey(value)) { sw.WriteLine("{0}|{1}|{2}|{3}", value, md5, size, assetTypeDict[value]); } else { sw.WriteLine("{0}|{1}|{2}", value, md5, size); } // UpdateProgress(i, includeFiles.Count, file); } sw.Close(); } // EditorUtility.ClearProgressBar(); Builder.AddBuildLog("<Asset Config Building> Build File Index end ...."); }
public static void WriteFile() { string path = Path.Combine(AssetBundleOutputPath, BuildUtil.GetPlatformFolder(EditorUserBuildSettings.activeBuildTarget)); path = path + "/assetMD5.txt"; string UpdaPath = Path.Combine(AssetBundleOutputPath, BuildUtil.GetPlatformFolder(EditorUserBuildSettings.activeBuildTarget)); UpdaPath = UpdaPath + "/updata.txt"; Dictionary <string, string> md5OldDict = new Dictionary <string, string>(); Dictionary <string, string> md5ChangDict = new Dictionary <string, string>(); if (File.Exists(path))//如果存在就删除 { StreamReader sr = new StreamReader(path, Encoding.Default); String line; while ((line = sr.ReadLine()) != null) { String[] md5 = line.Split(':'); if (!md5OldDict.ContainsKey(md5[1])) { if (md5.Length >= 3) { md5OldDict.Add(md5[1], md5[3]); } } else { Debug.LogError("have same key :" + md5[1]); } } sr.Dispose(); sr.Close(); //资源更新完才能删 File.Delete(path); } FileStream fs = new FileStream(path, FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.Write("Version:" + PlayerSettings.bundleVersion + "\r\n"); //sw.Write(System.Environment.NewLine); sw.Write("VersionCode:" + PlayerSettings.Android.bundleVersionCode + "\r\n"); //sw.Write(System.Environment.NewLine); long size = 0; //开始写入 foreach (KeyValuePair <string, string> kvp in md5Dict) { if (!md5OldDict.ContainsKey(kvp.Key)) { if (md5ChangDict.ContainsKey(kvp.Key)) { Debug.LogError("have same key :" + kvp.Key); } else { md5ChangDict.Add(kvp.Key, kvp.Value); } } if (SizeDict.ContainsKey(kvp.Key)) { size = SizeDict[kvp.Key]; } sw.Write("Name:" + kvp.Key + ":" + "MD5:" + kvp.Value + ":Size:" + size + "\r\n"); // sw.Write("MD5:" + kvp.Key + ": Name:" + kvp.Value); //sw.Write(System.Environment.NewLine); } //清空缓冲区 sw.Flush(); //关闭流 sw.Close(); fs.Close(); if (File.Exists(UpdaPath))//如果存在就删除 { File.Delete(UpdaPath); } fs = new FileStream(UpdaPath, FileMode.Create); sw = new StreamWriter(fs); foreach (KeyValuePair <string, string> kvp in md5ChangDict) { sw.Write("Name:" + kvp.Key + ":" + "MD5:" + kvp.Value + "\r\n"); // sw.Write("MD5:" + kvp.Key + ": Name:" + kvp.Value); //sw.Write(System.Environment.NewLine); } //清空缓冲区 sw.Flush(); //关闭流 sw.Close(); fs.Close(); }
private static List <string> searchFilesRecuivse(string rootPath, Dictionary <string, List <AssetBuildRule> > ruleMap, HashSet <string> includeSuffixs) { DirectoryInfo dirInfo = new DirectoryInfo(rootPath); if (!dirInfo.Exists) { return(null); } List <string> files = new List <string>(); string[] allFiles = Directory.GetFiles(rootPath, "*.*", SearchOption.TopDirectoryOnly) .Where(f => includeSuffixs.Contains(Path.GetExtension(f).ToLower())).ToArray(); for (int i = 0; i < allFiles.Length; i++) { string relativePath = BuildUtil.RelativePaths(allFiles[i]); bool isIgnore = false; List <AssetBuildRule> buildRule = null; if (ruleMap.TryGetValue(relativePath, out buildRule)) { //一个文件只有一个规则 if (buildRule.Count > 1) { Debug.LogError("One file have mul bundle rules !" + buildRule.Count + ", path is " + relativePath); } isIgnore = buildRule[0].BuildType == (int)BundleBuildType.Ignore; } if (!isIgnore) { files.Add(relativePath); } } DirectoryInfo[] childDirs = dirInfo.GetDirectories(); foreach (DirectoryInfo childDir in childDirs) { List <AssetBuildRule> buildRules = null; string relativePath = BuildUtil.RelativePaths(childDir.FullName); List <string> childFiles = null; if (ruleMap.TryGetValue(relativePath, out buildRules)) { HashSet <string> newIncludeSuffixs = new HashSet <string>(); for (int i = 0; i < buildRules.Count; i++) { AssetBuildRule rule = buildRules[i]; if (rule.BuildType == (int)BundleBuildType.Ignore) { continue; } string[] extends = GetFileExtension(rule.FileFilterType); for (int j = 0; j < extends.Length; j++) { newIncludeSuffixs.Add(extends[j]); } } childFiles = searchFilesRecuivse(relativePath, ruleMap, newIncludeSuffixs); } else { childFiles = searchFilesRecuivse(relativePath, ruleMap, includeSuffixs); } if (childFiles != null) { files.AddRange(childFiles); } } return(files); }