private bool mCurSaveBinary; //是否保存二进制文件 private void OnEnable() { if (VFS_Platform != null) { flag_platform_from_param = true; platform_from_param = VFS_Platform.Value; //如果参数给的是平台,那么要倒推出,当前该平台可用的分支 string[] main_package_branches = VFSManagerEditor.VersionManager.GetBranchNamesByMainPackage(platform_from_param); if (main_package_branches != null && main_package_branches.Length > 0) { match_branches_from_param.AddRange(main_package_branches); } string platform_name = XPlatformUtil.GetNameText(platform_from_param); string source_packages_folder_path = Path.Combine(VFSEditorConst.PROJECT_VFS_SOURCE_PACKAGES_ROOT_PATH, platform_name); string[] extension_groups_in_source_package_folder = VFSUtil.GetValidExtensionGroupNames(VFSUtil.GetExtensionPackageRootFolderInPackages(source_packages_folder_path)); foreach (var groupName in extension_groups_in_source_package_folder) { string[] group_branches = VFSManagerEditor.VersionManager.GetBranchNamesByExtensionGroup(platform_from_param, groupName); if (group_branches != null && group_branches.Length > 0) { match_branches_from_param.AddRange(group_branches); } } match_branches_from_param_arr = match_branches_from_param.ToArray(); } if (!BranchName.IsNullOrEmpty()) { flag_branchName_from_param = true; branchName_from_param = BranchName; isBrancNameFromParamValid = VFSManagerEditor.VersionManager.TryGetVersionBranch(branchName_from_param, out mCurBranch); mCurSelectBranchName = BranchName; } }
public bool AddBranch(string branchName, VersionBranch.BranchType type, XRuntimePlatform platform, string desc = null, string extGroupName = null) { if (!branchName.IsValidFileName()) { return(false); } if (this.IsBranchExists(branchName)) { return(false); } if (type == VersionBranch.BranchType.ExtensionGroup && extGroupName.IsNullOrEmpty()) { return(false); } mVersionMainData.Branches_ReadWrite.Add(branchName); var branch = new VersionBranch(); branch.BranchName = branchName; branch.BType = type; branch.Desc = desc; branch.ExtensionGroupName = extGroupName; branch.Platform = platform; if (mDict_Branches.ContainsKey(branchName)) { mDict_Branches[branchName] = branch; } else { mDict_Branches.Add(branchName, branch); } SaveVersionMainData(ref mVersionMainData, mVersionMainFilePath); SaveBranchFile(ref branch); return(true); }
public string[] GetBranchNamesByExtensionGroup(XRuntimePlatform platform, string extensionGroupName) { List <string> result = new List <string>(); foreach (var item in mDict_Branches) { if (item.Value.BType == VersionBranch.BranchType.ExtensionGroup && item.Value.Platform == platform && item.Value.ExtensionGroupName == extensionGroupName) { result.Add(item.Key); } } return(result.ToArray()); }
public string[] GetBranchNamesByMainPackage(XRuntimePlatform platform) { List <string> result = new List <string>(); foreach (var item in mDict_Branches) { if (item.Value.BType == VersionBranch.BranchType.MainPackage && item.Value.Platform == platform) { result.Add(item.Key); } } return(result.ToArray()); }
private void SaveExtensionGroupInfo(string group_path, string group_name, XRuntimePlatform platform, long mainPackageVersionLimit, string ab_ext_name) { string file_path = VFSUtil.GetExtensionGroup_GroupInfo_Path_InGroupPath(group_path); var obj = new ExtensionGroupInfo { Platform = platform, GroupName = group_name, MainPackageVersionLimit = mainPackageVersionLimit, AssetBundleExtension = ab_ext_name }; XConfig.SaveJson(obj, file_path, AssetLoadType.SystemIO); }
public void Build(XRuntimePlatform platform, AssetCompressType compressType) { Debug.Log("[TinaX.VFS] Start build assets..."); if (ClearAssetBundleSignBeforeBuild) { VFSEditorUtil.RemoveAllAssetbundleSigns(); } Debug.Log(" handle assetbundle signs..."); RefreshAssetBundleSign(); Debug.Log(" build assetbundles by unity editor."); string packages_root_path; //VFS存放相关文件的根目录 string output_temp_path; //Unity自身打包后直接输出的目录 BuildAssetBundle(platform, compressType, out packages_root_path, out output_temp_path); #region 加载Build得到的AssetbundleManifest文件 string abmanifest_file_name = Path.GetFileName(output_temp_path); string abmanifest_path = Path.Combine(output_temp_path, abmanifest_file_name); AssetBundle ab_mainifest = AssetBundle.LoadFromFile(abmanifest_path); mAssetBundleManifest = ab_mainifest.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); #endregion HandleVFSFiles(packages_root_path, output_temp_path, platform); SaveAssetHashFiles(Path.Combine(packages_root_path, VFSEditorConst.PROJECT_VFS_FILE_FOLDER_DATA)); MakeEditorBuildInfo(packages_root_path); MakeBuildInfo(packages_root_path); MakeVFSConfig(packages_root_path, Config); if (CopyToStreamingAssetsFolder) { CopyToStreamingAssets(packages_root_path, XPlatformUtil.GetNameText(platform)); } if (ClearAssetBundleSignAfterBuild) { VFSEditorUtil.RemoveAllAssetbundleSigns(); } Debug.Log("[TinaX.VFS] Build Finished."); }
public static UnityEditor.BuildTarget GetBuildTarget(XRuntimePlatform xPlatform) { switch (xPlatform) // !! Visual Studio 会给这地方建议改成C#8的模式匹配表达式,不要动,Unity目前只支持C#7.2语法!! { default: return(UnityEditor.BuildTarget.NoTarget); case XRuntimePlatform.Windows: return(UnityEditor.BuildTarget.StandaloneWindows64); case XRuntimePlatform.UniversalWindowsPlatform: return(UnityEditor.BuildTarget.WSAPlayer); case XRuntimePlatform.Linux: return(UnityEditor.BuildTarget.StandaloneLinux64); case XRuntimePlatform.OSX: return(UnityEditor.BuildTarget.StandaloneOSX); case XRuntimePlatform.iOS: return(UnityEditor.BuildTarget.iOS); case XRuntimePlatform.Android: return(UnityEditor.BuildTarget.Android); case XRuntimePlatform.XBox: return(UnityEditor.BuildTarget.XboxOne); case XRuntimePlatform.PS4: return(UnityEditor.BuildTarget.PS4); case XRuntimePlatform.NSwitch: return(UnityEditor.BuildTarget.Switch); case XRuntimePlatform.Windows32: return(UnityEditor.BuildTarget.StandaloneWindows); } }
public static string GetNameText(XRuntimePlatform xPlatform) { switch (xPlatform) { default: return(xPlatform.ToString().ToLower()); case XRuntimePlatform.Windows: return("windows_amd64"); //标注amd64, 区别于Windows后搞出来的arm64 case XRuntimePlatform.UniversalWindowsPlatform: return("uwp"); case XRuntimePlatform.Linux: return("gnu_linux_64"); case XRuntimePlatform.OSX: return("osx"); case XRuntimePlatform.iOS: return("ios"); case XRuntimePlatform.Android: return("android"); case XRuntimePlatform.XBox: return("xbox"); case XRuntimePlatform.PS4: return("ps4"); case XRuntimePlatform.NSwitch: return("switch"); case XRuntimePlatform.Windows32: return("windows_x86_32"); } }
private void OnGUI() { GUILayout.Label(IsChinese ? "创建新分支" : "Create Branch"); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(IsChinese ? "分支名" : "branchName", GUILayout.Width(100)); mBranchName = EditorGUILayout.TextField(mBranchName); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(IsChinese ? "分支类型" : "BranchType", GUILayout.Width(100)); mSelect_BranchType = (VersionBranch.BranchType)EditorGUILayout.EnumPopup(mSelect_BranchType); EditorGUILayout.EndHorizontal(); if (mSelect_BranchType == VersionBranch.BranchType.ExtensionGroup) { if (flag_refreshExtGroupDatas == false) { refreshExtensionGroupDatas(); } if (ExtensionGroupNames.Length == 0) { GUILayout.Label(IsChinese ? "没有可扩展组" : "No Extension Group."); } else { EditorGUILayout.BeginHorizontal(); GUILayout.Label(IsChinese ? "扩展组" : "ExtensionGroup:", GUILayout.Width(100)); select_extGroup_index = EditorGUILayout.Popup(select_extGroup_index, ExtensionGroupNames); EditorGUILayout.EndHorizontal(); mExtensionGroupName = ExtensionGroupNames[select_extGroup_index]; } } EditorGUILayout.BeginHorizontal(); GUILayout.Label(IsChinese ? "目标平台" : "Platform", GUILayout.Width(100)); mSelect_platform = (XRuntimePlatform)EditorGUILayout.EnumPopup(mSelect_platform); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(IsChinese ? "分支描述" : "description", GUILayout.Width(100)); mBranchDesc = EditorGUILayout.TextArea(mBranchDesc); EditorGUILayout.EndHorizontal(); GUILayout.Space(15); if (GUILayout.Button(IsChinese ? "新建" : "Create")) { if (!mBranchName.IsValidFileName()) { EditorUtility.DisplayDialog(IsChinese ? "有点问题" : "Oops", IsChinese ? "输入的分支名是无效的" : "Branch name you input is invalid.", IsChinese ? "好吧" : "Okey"); return; } //分支名查重 if (VFSManagerEditor.VersionManager.IsBranchExists(mBranchName)) { EditorUtility.DisplayDialog(IsChinese ? "有点问题" : "Oops", IsChinese ? "输入的分支名已存在" : "Branch name you input is exists.", IsChinese ? "好吧" : "Okey"); return; } //分支类型和名称确定 if (mSelect_BranchType == VersionBranch.BranchType.ExtensionGroup && mExtensionGroupName.IsNullOrEmpty()) { EditorUtility.DisplayDialog(IsChinese ? "有点问题" : "Oops", IsChinese ? "扩展组名称无效" : "Extension group name you input is invalid.", IsChinese ? "好吧" : "Okey"); return; } if (!mBranchDesc.IsNullOrEmpty() && mBranchDesc.Length > 512) { mBranchDesc = mBranchDesc.Substring(0, 512); } if (VFSManagerEditor.VersionManager.AddBranch(mBranchName, mSelect_BranchType, mSelect_platform, mBranchDesc, mExtensionGroupName)) { EditorUtility.DisplayDialog(IsChinese ? "完成" : "Success", IsChinese ? "创建成功" : "Create branch success.", IsChinese ? "好的" : "Ok"); this.Close(); } else { this.ShowNotification(new GUIContent(IsChinese ? "创建成功" : "创建失败")); } } }
/// <summary> /// /// </summary> /// <param name="root_path">存放一系列VFS目录的根目录</param> /// <param name="build_root_path">Unity的Build结果输出目录</param> public void HandleVFSFiles(string root_path, string build_root_path, XRuntimePlatform platform) { mEditorBuildInfo = new EditorBuildInfo(); List <VFSEditorGroup> groups = VFSManagerEditor.GetGroups(); string remote_files_root_path = Path.Combine(root_path, VFSEditorConst.PROJECT_VFS_FILE_FOLDER_REMOTE); string local_files_root_path = Path.Combine(root_path, VFSEditorConst.PROJECT_VFS_FILES_FOLDER_MAIN); string source_packages_extension_root_folder = Path.Combine(root_path, VFSEditorConst.PROJECT_VFS_FILES_FOLDER_EXTENSION); XDirectory.DeleteIfExists(remote_files_root_path, true); XDirectory.DeleteIfExists(local_files_root_path, true); XDirectory.DeleteIfExists(source_packages_extension_root_folder, true); foreach (var group in groups) { //扩展组的判断 if (group.ExtensionGroup) { #region 处理扩展组 string extension_group_root_path = Path.Combine(source_packages_extension_root_folder, group.GroupName.ToLower()); bool moved = CopyAssetBundleFilesByGroup(group, build_root_path, extension_group_root_path); if (moved) { //manifest group.MakeVFSManifest(root_path, mDict_Group_AssetBundleNames[group.GroupName], ref mAssetBundleManifest); //给独立的组生成一份hash group.MakeAssetBundleFilesHash(root_path, extension_group_root_path, mDict_Group_AssetBundleNames[group.GroupName]); SaveExtensionGroupInfo(extension_group_root_path, group.GroupName, platform, group.ExtensionGroup_MainPackageVersionLimit, Config.AssetBundleFileExtension); //保存Options group.SaveGroupOptionFile(root_path); } #endregion //登记 if (curProfile.IsDisabledGroup(group.GroupName)) { mEditorBuildInfo.list_disable_extension.Add(group.GroupName); } else { mEditorBuildInfo.list_total_extension.Add(group.GroupName); if (group.HandleMode == GroupHandleMode.LocalOrRemote) { if (curProfile.TryGetGroupLocation(group.GroupName, out var location)) { if (location == ProfileRecord.E_GroupAssetsLocation.Local) { mEditorBuildInfo.list_extension_local.Add(group.GroupName); } else if (location == ProfileRecord.E_GroupAssetsLocation.Remote) { mEditorBuildInfo.list_extension_remote.Add(group.GroupName); } } else { mEditorBuildInfo.list_extension_local.Add(group.GroupName); } } else if (group.HandleMode == GroupHandleMode.RemoteOnly) { mEditorBuildInfo.list_extension_remote.Add(group.GroupName); } else { mEditorBuildInfo.list_extension_local.Add(group.GroupName); } } } else { bool moveToRemote = false; bool moveToLocal = false; if (group.HandleMode == GroupHandleMode.LocalOrRemote) { if (curProfile.TryGetGroupLocation(group.GroupName, out var location)) { if (location == ProfileRecord.E_GroupAssetsLocation.Remote) { moveToRemote = true; } else { moveToLocal = true; } } else { moveToLocal = true; } } else if (group.HandleMode == GroupHandleMode.RemoteOnly) { moveToRemote = true; } else if (group.HandleMode == GroupHandleMode.LocalOnly || group.HandleMode == GroupHandleMode.LocalAndUpdatable) { moveToLocal = true; } //登记 mEditorBuildInfo.list_total_main_package.Add(group.GroupName); if (moveToRemote) { //登记 mEditorBuildInfo.list_main_package_remote.Add(group.GroupName); XDirectory.CreateIfNotExists(remote_files_root_path); CopyAssetBundleFilesByGroup(group, build_root_path, remote_files_root_path); //上一步copy的时候,开发者自定义的pipeline可以改变文件,所以制作assetbundle的hash信息的时候,必须使用上一步处理后的结果 group.MakeAssetBundleFilesHash(root_path, remote_files_root_path, mDict_Group_AssetBundleNames[group.GroupName]); } else if (moveToLocal) { //登记 mEditorBuildInfo.list_main_package_local.Add(group.GroupName); XDirectory.CreateIfNotExists(local_files_root_path); CopyAssetBundleFilesByGroup(group, build_root_path, local_files_root_path); //上一步copy的时候,开发者自定义的pipeline可以改变文件,所以制作assetbundle的hash信息的时候,必须使用上一步处理后的结果 group.MakeAssetBundleFilesHash(root_path, local_files_root_path, mDict_Group_AssetBundleNames[group.GroupName]); } group.MakeVFSManifest(root_path, mDict_Group_AssetBundleNames[group.GroupName], ref mAssetBundleManifest); } } }
public void BuildAssetBundle(XRuntimePlatform platform, AssetCompressType compressType, out string output_folder, out string temp_output_folder) { var buildTarget = XPlatformEditorUtil.GetBuildTarget(platform); var target_name = XPlatformUtil.GetNameText(platform); output_folder = Path.Combine(VFSEditorConst.PROJECT_VFS_SOURCE_PACKAGES_ROOT_PATH, target_name); string build_output_folder = Path.Combine(output_folder, "build_temp"); temp_output_folder = build_output_folder; if (ClearOutputFolder) { XDirectory.DeleteIfExists(output_folder, true); } XDirectory.CreateIfNotExists(output_folder); XDirectory.CreateIfNotExists(temp_output_folder); //压缩方法 BuildAssetBundleOptions build_opt = BuildAssetBundleOptions.None; switch (compressType) { default: case AssetCompressType.LZ4: build_opt = BuildAssetBundleOptions.ChunkBasedCompression; break; case AssetCompressType.LZMA: build_opt = BuildAssetBundleOptions.None; break; case AssetCompressType.None: build_opt = BuildAssetBundleOptions.UncompressedAssetBundle; break; } //强制重新构建 if (ForceRebuild) { build_opt = build_opt | BuildAssetBundleOptions.ForceRebuildAssetBundle; } //严格模式 if (StrictMode) { build_opt = build_opt | BuildAssetBundleOptions.StrictMode; } //Hash保持一致 build_opt = build_opt | BuildAssetBundleOptions.DeterministicAssetBundle; //叫Unity来打ab包 BuildPipeline.BuildAssetBundles(build_output_folder, build_opt, buildTarget); //打包完了,把所有打包得到的AssetBundle文件记录下来 string ab_extension = Config.AssetBundleFileExtension; if (!ab_extension.StartsWith(".")) { ab_extension = "." + ab_extension; } string[] files = Directory.GetFiles(build_output_folder, $"*{ab_extension}", SearchOption.AllDirectories); #region temp下的目录完全hash //var hashBook = new FilesHashBook(); //List<FilesHashBook.FileHash> temp_hash_list = new List<FilesHashBook.FileHash>(); //int build_output_folder_len = build_output_folder.Length + 1; //foreach (var file in files) //{ // string pure_path = file.Substring(build_output_folder_len, file.Length - build_output_folder_len); // if (pure_path.IndexOf("\\") != -1) // pure_path = pure_path.Replace("\\", "/"); // temp_hash_list.Add(new FilesHashBook.FileHash() // { // p = pure_path, // h = XFile.GetMD5(file, true) // }); //} //hashBook.Files = temp_hash_list.ToArray(); //string hashBook_path = Path.Combine(build_output_folder, VFSConst.ABsHashFileName); //XFile.DeleteIfExists(hashBook_path); //string hashBook_json = JsonUtility.ToJson(hashBook); //File.WriteAllText(hashBook_path, hashBook_json, Encoding.UTF8); #endregion }
public void BuildAssetBundle(XRuntimePlatform platform, AssetCompressType compressType) { this.BuildAssetBundle(platform, compressType, out _, out _); }
private void OnGUI() { GUILayout.BeginVertical(style_body); #region Profile 选择 if (xprofiles == null || (select_xprofile - 1) > xprofiles.Length) { refreshXprofilesCacheData(); } if (mDevelopMode) { GUILayout.Label("[Develop Mode]", style_warning); } GUILayout.BeginHorizontal(style_profile_selector); GUILayout.Label("Profile:", GUILayout.Width(55)); //select_xprofile = EditorGUILayout.Popup(select_xprofile, xprofiles); GUILayout.Label(xprofiles[select_xprofile]); if (GUILayout.Button(VFSBuilderI18N.SwitchProfile, GUILayout.Width(50))) { SettingsService.OpenProjectSettings(XEditorConst.ProjectSetting_CorePath); } GUILayout.EndHorizontal(); #endregion if (xprofiles != null && xprofiles.Length > 0) { cur_select_xprofile_name = xprofiles[select_xprofile]; } #region 平台选择 EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.PlatformTarget, GUILayout.MaxWidth(100)); cur_select_platform = (XRuntimePlatform)EditorGUILayout.EnumPopup(cur_select_platform); EditorGUILayout.EndHorizontal(); #endregion #region 严格模式 EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.strictMode, GUILayout.Width(100)); cur_strictMode = EditorGUILayout.Toggle(cur_strictMode); EditorGUILayout.EndHorizontal(); #endregion #region 压缩设置 EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.AssetCompressType, GUILayout.MaxWidth(100)); cur_select_compress = (AssetCompressType)EditorGUILayout.EnumPopup(cur_select_compress); EditorGUILayout.EndHorizontal(); #endregion #region 制到StreamingAssets EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.CopyToStramingAssetPath, GUILayout.MaxWidth(200)); cur_copyToStreamingAssetFolder = EditorGUILayout.Toggle(cur_copyToStreamingAssetFolder); EditorGUILayout.EndHorizontal(); #endregion #region 在结束前清理AB标记 EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.ClearAllABSignBeforeStart); cur_clearAllABSign = EditorGUILayout.Toggle(cur_clearAllABSign); EditorGUILayout.EndHorizontal(); GUILayout.Label(VFSBuilderI18N.ClearAllABSignBeforeStart_Tips, EditorStyles.helpBox); #endregion #region 在结束后清理AB标记 EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.ClearAllABSignAfterFinish); cur_clearAllABSignAfterFinish = EditorGUILayout.Toggle(cur_clearAllABSignAfterFinish); EditorGUILayout.EndHorizontal(); #endregion #region 清理输出目录 EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.ClearOutputFolders); cur_ClearOutputFolder = EditorGUILayout.Toggle(cur_ClearOutputFolder); EditorGUILayout.EndHorizontal(); #endregion #region 强制重构建资源 EditorGUILayout.BeginHorizontal(); GUILayout.Label(VFSBuilderI18N.ForceRebuild); cur_ForceRebuild = EditorGUILayout.Toggle(cur_ForceRebuild); EditorGUILayout.EndHorizontal(); #endregion #region 管线 if (mPipeline_ready == false) { refreshBuildPipline(); } if (mList_pipeline != null && mList_pipeline.Count > 0) { GUILayout.Space(15); TinaXEditor.Utils.EditorGUIUtil.HorizontalLine(); GUILayout.Label("Builder Pipeline:"); v2_scroll_pipeline = EditorGUILayout.BeginScrollView(v2_scroll_pipeline); foreach (var type in mList_pipeline) { if (type.Namespace.IsNullOrEmpty()) { GUILayout.Label($"- {type.FullName} [{type.Assembly.ManifestModule.Name}]"); } else { GUILayout.Label($"- {type.Namespace}.{type.FullName} [{type.Assembly.ManifestModule.Name}]"); } } EditorGUILayout.EndScrollView(); } #endregion //#region Preview //GUILayout.BeginVertical(style_preview); //GUILayout.Label("Build Priview", EditorStyles.centeredGreyMiniLabel); //GUILayout.Label("Build Group:"); //GUILayout.FlexibleSpace(); //GUILayout.EndVertical(); //#endregion EditorGUILayout.Space(); if (GUILayout.Button("Build", style_btn_build)) { runBuild(); } if (GUILayout.Button(VFSBuilderI18N.RemoveAllAssetBundleSign)) { if (EditorUtility.DisplayDialog("Clear?", "Are you sure?", "yes", "no")) { VFSEditorUtil.RemoveAllAssetbundleSigns(true); } } if (GUILayout.Button(VFSBuilderI18N.CreateVersionRecord)) { CreateVersionRecordGUI.VFS_Platform = cur_select_platform; CreateVersionRecordGUI.OpenUI(); } EditorGUILayout.Space(); GUILayout.EndVertical(); }