/// <summary> /// 打包资源 /// </summary> public void BuildAsset() { RuntimePlatform platform = RuntimePlatform.Android; BuildTarget buildTarget = BuildTarget.Android; if (isSelectAndroid) { platform = RuntimePlatform.Android; buildTarget = BuildTarget.Android; } else if (isSelectIOS) { platform = RuntimePlatform.IPhonePlayer; buildTarget = BuildTarget.iOS; } var outPath = exportPath + "/" + BApplication.GetPlatformPath(platform); var config = GameObject.Find("BDFrame").GetComponent <Config>(); //根据版本进入不同打包模式 if (config.Data.AssetBundleManagerVersion == AssetBundleManagerVersion.V1) { AssetBundleEditorTools.GenAssetBundle(outPath, buildTarget, options); } else if (config.Data.AssetBundleManagerVersion == AssetBundleManagerVersion.V2_experiment) { AssetBundleEditorToolsV2.GenAssetBundle(outPath, buildTarget, options, AES: AES); } AssetDatabase.Refresh(); Debug.Log("资源打包完毕"); }
/// <summary> /// 更新服务器配置 /// </summary> /// <param name="callback"></param> /// <returns></returns> private IEnumerator UpdateServerConfig(Action callback) { var url = string.Format("{0}/{1}/{2}", Data.FileServerUrl, BApplication.GetPlatformPath(Application.platform), "GameConfig.json"); Debug.Log(url); UnityWebRequest uwq = UnityWebRequest.Get(url); GameConfig gconfig = null; yield return(uwq.SendWebRequest()); if (uwq.isDone && uwq.error == null) { var text = uwq.downloadHandler.text; if (!string.IsNullOrEmpty(text)) { gconfig = JsonMapper.ToObject <GameConfig>(text); BDebug.Log("使用服务器配置:\n" + text); } } else { BDebug.LogError("Game配置无法更新,使用本地"); } SetNewConfig(gconfig); callback?.Invoke(); }
/// <summary> /// 分析dll生成 /// </summary> /// <param name="platform"></param> /// <param name="dllpath"></param> static private void GenCLRBindingByAnalysis(RuntimePlatform platform = RuntimePlatform.Lumin, string dllpath = "") { if (platform == RuntimePlatform.Lumin) { platform = Application.platform; } //默认读StreammingAssets下面path if (dllpath == "") { dllpath = Application.streamingAssetsPath + "/" + BApplication.GetPlatformPath(platform) + DLLPATH; } //不参与自动绑定的 List <Type> excludeTypes = new List <Type>(); // excludeTypes.AddRange(manualBindingTypes); excludeTypes.AddRange(preBindingTypes); //用新的分析热更dll调用引用来生成绑定代码 var targetPath = "Assets/Code/Game/ILRuntime/Binding/Analysis"; ILRuntimeHelper.LoadHotfix(dllpath, false); BindingCodeGenerator.GenerateAnalysisBindingCode(ILRuntimeHelper.AppDomain, targetPath, blackTypes: excludeTypes); ILRuntimeHelper.Close(); AssetDatabase.Refresh(); //暂时先不处理 }
/// <summary> /// 打包资源 /// </summary> public void BuildAsset() { RuntimePlatform platform = RuntimePlatform.Android; BuildTarget buildTarget = BuildTarget.Android; // if (isSelectWindows) // { // platform = RuntimePlatform.WindowsPlayer; // buildTarget = BuildTarget.StandaloneWindows; // } // else if (isSelectAndroid) { platform = RuntimePlatform.Android; buildTarget = BuildTarget.Android; } else if (isSelectIOS) { platform = RuntimePlatform.IPhonePlayer; buildTarget = BuildTarget.iOS; } AssetBundleEditorTools.GenAssetBundle(exportPath + "/" + BApplication.GetPlatformPath(platform), buildTarget, options); AssetDatabase.Refresh(); Debug.Log("资源打包完毕"); }
/// <summary> /// 初始化 /// </summary> /// <param name="path"></param> /// <param name="onInitEnd"></param> public void Init(string path, Action onInitEnd) { //多热更切换,需要卸载 if (this.loder != null) { this.UnloadAllAsset(); GC.Collect(); } this.AssetbundleMap = new Dictionary <string, AssetBundleWapper>(); this.allTaskGroupList = new List <LoaderTaskGroup>(); //1.设置加载路径 artRootPath = (path + "/" + BApplication.GetPlatformPath(Application.platform) + "/Art").Replace("\\", "/"); secArtRootPath = (Application.streamingAssetsPath + "/" + BApplication.GetPlatformPath(Application.platform) + "/Art") .Replace("\\", "/"); // string configPath = FindAsset("Config.json"); BDebug.Log("AssetBundle Version: V2", "red"); BDebug.Log("Art加载路径:" + configPath, "red"); // this.loder = new ManifestLoder(); this.loder.Load(configPath, onInitEnd); }
/// <summary> /// SVN提交 /// </summary> static private void SVNCommit(SVNProcessor svnProcessor) { //存在仓库 var svntag = svnProcessor.LocalSVNRootPath + "/.svn"; if (Directory.Exists(svntag)) { //1.获取被删除文件提交 var delFiles = svnProcessor.GetStatus(SVNProcessor.Status.Deleted); svnProcessor.Delete(delFiles); //2.获取支持的目录,提交 foreach (var platform in BApplication.SupportPlatform) { var p = BApplication.GetPlatformPath(platform); var path = Path.Combine(svnProcessor.LocalSVNRootPath, p); if (Directory.Exists(path)) { //添加文件夹 svnProcessor.AddFloder(path); //添加所有文件 var fs = Directory.GetFiles(path, "*", SearchOption.AllDirectories); svnProcessor.Add(fs); } } //提交 svnProcessor.Commit(); } }
private void Onclick_DownLoadAndLaunch() { //删除本地的文件 var cachedir = IPath.Combine(Application.persistentDataPath, BApplication.GetPlatformPath(Application.platform)); if (Directory.Exists(cachedir)) { Directory.Delete(cachedir, true); } var url = "http://" + this.inputField.text; VersionContorller.Start(UpdateMode.Repair, url, Application.persistentDataPath, (i, j) => { this.text_DownloadProcess.text = string.Format("{0}/{1}", i, j); //下载完毕 if (i == j) { this.text_DownloadProcess.text = "下载完毕"; //启动 GameObject.Find("BDFrame").GetComponent <BDLauncher>().Launch(); } }, (e) => { this.text_DownloadProcess.text = e; }); }
/// <summary> /// 添加混淆 /// </summary> public void MixAssetBundle(string outpath, RuntimePlatform platform) { var mixAssets = GetMixAssets(); //构建ab管理器对象 AssetBundleMgrV2 abv2 = new AssetBundleMgrV2(); abv2.Init(outpath); // var mixAssetbundleItems = abv2.AssetConfigLoder.AssetbundleItemList.Where((i) => mixAssets.Contains(i.AssetBundlePath)).ToArray(); Debug.Log("<color=green>--------------------开始混淆Assetbundle------------------------</color>"); //开始混淆AssetBundle for (int i = 0; i < abv2.AssetConfigLoder.AssetbundleItemList.Count; i++) { //源AB var sourceItem = abv2.AssetConfigLoder.AssetbundleItemList[i]; //非混合文件、ab不存在、mix过 if (mixAssetbundleItems.Contains(sourceItem) || sourceItem.AssetBundlePath == null || sourceItem.Mix > 0) { continue; } var idx = (int)(Random.Range(0, (mixAssetbundleItems.Length - 1) * 10000) / 10000); var mixItem = mixAssetbundleItems[idx]; // var mixBytes = File.ReadAllBytes(IPath.Combine(outpath, BApplication.GetPlatformPath(platform), BResources.ART_ASSET_ROOT_PATH, mixItem.AssetBundlePath)); var abpath = IPath.Combine(outpath, BApplication.GetPlatformPath(platform), BResources.ART_ASSET_ROOT_PATH, sourceItem.AssetBundlePath); var abBytes = File.ReadAllBytes(abpath); //拼接 var outbytes = new byte[mixBytes.Length + abBytes.Length]; Array.Copy(mixBytes, 0, outbytes, 0, mixBytes.Length); Array.Copy(abBytes, 0, outbytes, mixBytes.Length, abBytes.Length); //写入 FileHelper.WriteAllBytes(abpath, outbytes); var hash = FileHelper.GetMurmurHash3(abpath); //相同ab的都进行赋值,避免下次重新被修改。 foreach (var item in abv2.AssetConfigLoder.AssetbundleItemList) { if (sourceItem.AssetBundlePath.Equals(item.AssetBundlePath)) { item.Mix = mixBytes.Length; item.Hash = hash; } } //sourceItem.Mix = mixBytes.Length; //混淆 Debug.Log("【Assetbundle混淆】" + sourceItem.AssetBundlePath); } //重新写入配置 abv2.AssetConfigLoder.OverrideConfig(); Debug.Log("<color=green>--------------------混淆Assetbundle完毕------------------------</color>"); }
/// <summary> /// 保存母包资源info /// </summary> /// <param name="ouptputPath"></param> /// <param name="platform"></param> /// <param name="info"></param> static public void SaveBasePackageBuildInfo(string ouptputPath, RuntimePlatform platform, BasePackageAssetsBuildInfo info) { //转json var content = JsonMapper.ToJson(info); //写入本地 var path = IPath.Combine(ouptputPath, BApplication.GetPlatformPath(platform), BResources.PACKAGE_BUILD_INFO_PATH); FileHelper.WriteAllText(path, content); }
/// <summary> /// 编译模式 /// </summary> /// <param name="mode"></param> static public void RoslynBuild(ScriptBuildTools.BuildMode mode, string outpath = null) { var targetPath = "Assets/Code/Game/ILRuntime/Binding/Analysis"; //分析之前先删除,然后生成临时文件防止报错 if (Directory.Exists(targetPath)) { Directory.Delete(targetPath, true); } var fileContent = @" namespace ILRuntime.Runtime.Generated { class CLRBindings { public static void Initialize(ILRuntime.Runtime.Enviorment.AppDomain app) { } } } "; FileHelper.WriteAllText(targetPath + "/CLRBindings.cs", fileContent); AssetDatabase.Refresh(); //这里必须要刷新 //没指定,走默认模式 if (string.IsNullOrEmpty(outpath)) { //1.build dll var outpath_win = Application.streamingAssetsPath + "/" + BApplication.GetPlatformPath(Application.platform); ScriptBuildTools.BuildDll(outpath_win, mode); //2.同步到其他两个目录 var outpath_android = Application.streamingAssetsPath + "/" + BApplication.GetPlatformPath(RuntimePlatform.Android) + DLLPATH; var outpath_ios = Application.streamingAssetsPath + "/" + BApplication.GetPlatformPath(RuntimePlatform.IPhonePlayer) + DLLPATH; var source = outpath_win + DLLPATH; var bytes = File.ReadAllBytes(source); if (source != outpath_android) { FileHelper.WriteAllBytes(outpath_android, bytes); } if (source != outpath_ios) { FileHelper.WriteAllBytes(outpath_ios, bytes); } } else { //指定了直接 build ScriptBuildTools.BuildDll(outpath, mode); } //3.预绑定 GenPreCLRBinding(); //4.生成AnalysisCLRBinding GenCLRBindingByAnalysis(); AssetDatabase.Refresh(); Debug.Log("脚本打包完毕"); }
/// <summary> /// 删除拷贝的资源 /// </summary> /// <param name="targetpath"></param> /// <param name="platform"></param> static public void DeleteCopyAssets(string targetpath, RuntimePlatform platform) { targetpath = IPath.Combine(targetpath, BApplication.GetPlatformPath(platform)); //优先删除拷贝的美术资源,防止构建完再导入 其他资源等工作流完全切入DevOps再进行删除 var copyArtPath = IPath.Combine(targetpath, BResources.ART_ASSET_ROOT_PATH); if (Directory.Exists(copyArtPath)) { Directory.Delete(copyArtPath, true); } }
/// <summary> /// 获取母包资源构建信息 /// </summary> /// <returns></returns> static public BasePackageAssetsBuildInfo GetPacakgeBuildInfo(string ouptputPath, RuntimePlatform platform) { var path = IPath.Combine(ouptputPath, BApplication.GetPlatformPath(platform), BResources.PACKAGE_BUILD_INFO_PATH); var buildinfo = new BasePackageAssetsBuildInfo(); if (File.Exists(path)) { var text = File.ReadAllText(path); buildinfo = JsonMapper.ToObject <BasePackageAssetsBuildInfo>(text); } return(buildinfo); }
/// <summary> /// 获取分包设置路径 /// </summary> /// <param name="rootPath"></param> /// <param name="platform"></param> /// <returns></returns> static public string GetAssetsSubPackageInfoPath(string rootPath, RuntimePlatform platform, string subPackageName) { //旧版本兼容逻辑 if (subPackageName.StartsWith("ServerAssetsSubPackage_")) { return(IPath.Combine(rootPath, BApplication.GetPlatformPath(platform), subPackageName)); } else { var subPackagePath = string.Format(BResources.SERVER_ASSETS_SUB_PACKAGE_INFO_PATH, subPackageName); return(IPath.Combine(rootPath, BApplication.GetPlatformPath(platform), subPackagePath)); } }
/// <summary> /// 清理旧的persistent资源 /// </summary> static private void ClearOldPersistentAssets() { var runtimes = BApplication.SupportPlatform; foreach (var runtime in runtimes) { var path = IPath.Combine(Application.persistentDataPath, BApplication.GetPlatformPath(runtime)); if (Directory.Exists(path)) { Directory.Delete(path, true); } } }
/// <summary> /// 资源转hash /// </summary> /// <param name="path"></param> /// <param name="uploadHttpApi"></param> static public void PublishAssetsToServer(string path) { foreach (var platform in BApplication.SupportPlatform) { //资源路径 var sourcePath = IPath.Combine(path, BApplication.GetPlatformPath(platform)); //大概判断原资源是否存在 if (Directory.Exists(sourcePath)) { var files = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories); if (files.Length < 5) { continue; } } else { continue; } //输出路径 var outputPath = IPath.Combine(IPath.ReplaceBackSlash(path), UPLOAD_FOLDER_SUFFIX, BApplication.GetPlatformPath(platform)); if (Directory.Exists(sourcePath)) { //对比Assets.info 是否一致 var sourceAssetsInfoPath = IPath.Combine(sourcePath, BResources.ASSETS_INFO_PATH); var outputAssetsInfoPath = IPath.Combine(outputPath, BResources.ASSETS_INFO_PATH); if (File.Exists(sourceAssetsInfoPath) && File.Exists(outputAssetsInfoPath)) { var sourceHash = FileHelper.GetMurmurHash3(sourceAssetsInfoPath); var outputHash = FileHelper.GetMurmurHash3(outputAssetsInfoPath); if (sourceHash == outputHash) { Debug.Log("【PublishPipeline】资源无改动,无需重新生成服务器文件. -" + BApplication.GetPlatformPath(platform)); continue; } } //获取资源版本号 var basePckInfo = GlobalAssetsHelper.GetPackageBuildInfo(path, platform); var versionNum = basePckInfo.Version; //发布资源处理前,处理前回调 BDFrameworkPipelineHelper.OnBeginPublishAssets(platform, sourcePath, versionNum); //处理资源 var outdir = GenServerHashAssets(path, platform, versionNum); //发布资源处理后,通知回调 BDFrameworkPipelineHelper.OnEndPublishAssets(platform, outdir, versionNum); Debug.Log("发布资源处理完成! 请继承PublishPipeline生命周期,完成后续自动化部署到自己的文件服务器!"); } } }
/// <summary> /// 加载本地的Asset.info /// </summary> private List <AssetItem> LoadLocalAssetInfo(RuntimePlatform platform) { var retList = new List <AssetItem>(); //优先加载persistent的Assets.info var persistentAssetInfoPath = BResources.GetAssetsInfoPath(BApplication.persistentDataPath, platform); if (File.Exists(persistentAssetInfoPath)) { var content = File.ReadAllText(persistentAssetInfoPath); retList = CsvSerializer.DeserializeFromString <List <AssetItem> >(content); } //streaming 和其他的Assets.info else { //根据加载模式不同,寻找不同目录下的其他配置 //打包时,本地会带一份ServerAssets.info以标记当前包携带的资源 var loadArtRoot = BDLauncher.Inst.GameConfig.ArtRoot; switch (loadArtRoot) { case AssetLoadPathType.Persistent: case AssetLoadPathType.StreamingAsset: { //TODO :BSA 读取,不需要Streaming前缀 var steamingAssetsInfoPath = IPath.Combine(BApplication.GetPlatformPath(platform), BResources.ASSETS_INFO_PATH); //var steamingAssetsInfoPath = GetAssetsInfoPath(BDApplication.streamingAssetsPath, platform); if (BetterStreamingAssets.FileExists(steamingAssetsInfoPath)) { var content = BetterStreamingAssets.ReadAllText(steamingAssetsInfoPath); retList = CsvSerializer.DeserializeFromString <List <AssetItem> >(content); } } break; case AssetLoadPathType.DevOpsPublish: { var path = GameConfig.GetLoadPath(loadArtRoot); var devopsAssetInfoPath = BResources.GetAssetsInfoPath(path, platform); if (File.Exists(devopsAssetInfoPath)) { var content = File.ReadAllText(devopsAssetInfoPath); retList = CsvSerializer.DeserializeFromString <List <AssetItem> >(content); } } break; } } return(retList); }
/// <summary> /// 是否存在资源文件 /// </summary> /// <param name="platform"></param> /// <param name="serverAsset"></param> /// <returns></returns> static public bool IsExsitAsset(RuntimePlatform platform, string assetName, string assetHashName) { //本地是否下载过hash文件(之前下到一半就中止了) var persistentHashPath = IPath.Combine(BApplication.persistentDataPath, BApplication.GetPlatformPath(platform), assetHashName); if (File.Exists(persistentHashPath)) { var hash = FileHelper.GetMurmurHash3(persistentHashPath); if (assetHashName.Equals(hash)) { return(true); } else { File.Delete(persistentHashPath); } } //persistent判断 var persistentAssetPath = IPath.Combine(BApplication.persistentDataPath, BApplication.GetPlatformPath(platform), assetName); if (File.Exists(persistentAssetPath)) { return(true); } /************母包资源的判断*************/ if (Application.isEditor && BDLauncher.Inst.GameConfig.ArtRoot == AssetLoadPathType.DevOpsPublish) { //devops var devopsAssetPath = IPath.Combine(BApplication.DevOpsPublishAssetsPath, BApplication.GetPlatformPath(platform), assetName); if (File.Exists(devopsAssetPath)) { return(true); } } else { //Streaming 文件判断,无需Streaming前缀 var streamingAssetPath = IPath.Combine(BApplication.GetPlatformPath(platform), assetName); if (BetterStreamingAssets.FileExists(streamingAssetPath)) { return(true); } } return(false); }
/// <summary> /// 清理persistent /// </summary> private void OnClick_ClearPersistent() { foreach (var runtime in BApplication.SupportPlatform) { var path = IPath.Combine(Application.persistentDataPath, BApplication.GetPlatformPath(runtime)); if (Directory.Exists(path)) { Directory.Delete(path, true); } } //清理完毕 var dirs = Directory.GetDirectories(Application.persistentDataPath, "*"); Debug.Log(Application.persistentDataPath); Debug.Log("清理完毕~,剩余目录:" + dirs.Length); }
/// <summary> /// 编译模式 /// </summary> /// <param name="mode"></param> static public void RoslynBuild(ScriptBuildTools.BuildMode mode, string outpath = null) { var targetPath = "Assets/Code/Game/ILRuntime/Binding/Analysis"; //1.分析之前先删除,然后生成临时文件防止报错 if (Directory.Exists(targetPath)) { Directory.Delete(targetPath, true); } var fileContent = @" namespace ILRuntime.Runtime.Generated { class CLRBindings { public static void Initialize(ILRuntime.Runtime.Enviorment.AppDomain app) { } } } "; FileHelper.WriteAllText(targetPath + "/CLRBindings.cs", fileContent); AssetDatabase.Refresh(); //这里必须要刷新 //2.生成DLL if (string.IsNullOrEmpty(outpath)) { //1.build dll var outpath_win = Application.streamingAssetsPath + "/" + BApplication.GetPlatformPath(Application.platform); ScriptBuildTools.BuildDll(outpath_win, mode); } else { //指定了直接 build ScriptBuildTools.BuildDll(outpath, mode); } //3.预绑定 //GenPreCLRBinding(); //4.生成自动分析绑定 GenCLRBindingByAnalysis(); AssetDatabase.Refresh(); Debug.Log("脚本打包完毕"); }
/// <summary> /// 初始化 /// </summary> /// <param name="rootPath"></param> public void Init(string rootPath, RuntimePlatform platform = RuntimePlatform.Android) { //多热更切换,需要卸载 if (this.AssetConfigLoder != null) { this.UnloadAllAsset(); } //平台 string platformPath = ""; //1.设置加载路径 if (Application.isEditor) { //editor下可以自行输入 platformPath = BApplication.GetPlatformPath(platform); firstArtDirectory = IPath.Combine(rootPath, platformPath, BResources.ART_ASSET_ROOT_PATH); secArtDirectory = IPath.Combine(Application.streamingAssetsPath, platformPath, BResources.ART_ASSET_ROOT_PATH); // } else { //runtime只能使用当前平台 platformPath = BApplication.GetRuntimePlatformPath(); firstArtDirectory = IPath.Combine(Application.persistentDataPath, platformPath, BResources.ART_ASSET_ROOT_PATH); secArtDirectory = IPath.Combine(Application.streamingAssetsPath, platformPath, BResources.ART_ASSET_ROOT_PATH); // rootPath = Application.persistentDataPath; } //2.寻址路径格式化 firstArtDirectory = IPath.FormatPathOnRuntime(firstArtDirectory); secArtDirectory = IPath.FormatPathOnRuntime(secArtDirectory); //3.加载ArtConfig this.AssetConfigLoder = GetAssetbundleConfigLoder(rootPath, platformPath); //开始异步任务刷新 IEnumeratorTool.StartCoroutine(this.IE_LoadTaskUpdate()); IEnumeratorTool.StartCoroutine(this.IE_UnLoadTaskUpdate()); BDebug.Log($"【AssetBundleV2】 firstDir:{firstArtDirectory}", "red"); BDebug.Log($"【AssetBundleV2】 secDir:{secArtDirectory}", "red"); }
/// <summary> /// 生成所有资源 /// </summary> /// <param name="exportPath"></param> /// <param name="platform"></param> /// <param name="target"></param> static public void GenAllAssets(string exportPath, RuntimePlatform platform, BuildTarget target) { var outPath = exportPath + "/" + BApplication.GetPlatformPath(platform); if (Directory.Exists(outPath)) { Directory.Delete(outPath, true); } //1.打包资源 try { //搜集keywork ShaderCollection.GenShaderVariant(); AssetBundleEditorTools.GenAssetBundle(outPath, target); } catch (Exception e) { Debug.LogError(e.Message); return; } //2.编译脚本 try { EditorWindow_ScriptBuildDll.RoslynBuild(ScriptBuildTools.BuildMode.Release, outPath); } catch (Exception e) { Debug.LogError(e.Message); return; } //3.打包表格 try { Excel2SQLiteTools.GenExcel2SQLite(exportPath, platform); } catch (Exception e) { Debug.LogError(e.Message); } }
/// <summary> /// 构建包体,使用当前配置、资源 /// </summary> static public bool BuildIpa(BuildMode buildMode, bool isGenAssets, string outdir) { bool ret = false; //增加平台路径 outdir = IPath.Combine(outdir, BApplication.GetPlatformPath(BuildTarget.iOS)); BDFrameworkPipelineHelper.OnBeginBuildPackage(BuildTarget.iOS, outdir); //0.加载场景和配置 LoadConfig(buildMode); //1.生成资源 if (isGenAssets) { BuildAssetsTools.BuildAllAssets(RuntimePlatform.IPhonePlayer, BApplication.DevOpsPublishAssetsPath); } //2.拷贝资源打包 AssetDatabase.StartAssetEditing(); //停止触发资源导入 { //拷贝资源 DevOpsTools.CopyPublishAssetsTo(Application.streamingAssetsPath, RuntimePlatform.IPhonePlayer); try { var(_ret, outputpath) = BuildIpa(buildMode, outdir); BDFrameworkPipelineHelper.OnEndBuildPackage(BuildTarget.iOS, outputpath); ret = _ret; } catch (Exception e) { //For ci throw e; } DevOpsTools.DeleteCopyAssets(Application.streamingAssetsPath, RuntimePlatform.IPhonePlayer); } AssetDatabase.StopAssetEditing(); //恢复触发资源导入 return(ret); }
/// <summary> /// 修复模式,是要对比本地文件是否存在 /// </summary> static public List <AssetItem> Repair(AssetConfig local, AssetConfig server) { if (local == null) { return(server.Assets); } var list = new List <AssetItem>(); //比对平台 if (local.Platfrom == server.Platfrom) { //平台 var platform = BApplication.GetPlatformPath(Application.platform); // foreach (var serverAsset in server.Assets) { //比较本地是否有 hash、文件名一致的资源 var result = local.Assets.Find((a) => a.HashName == serverAsset.HashName && a.LocalPath == serverAsset.LocalPath); //配置不存在 if (result == null) { list.Add(serverAsset); } else { //配置存在,判断文件存不存在,存在还要判断hash var fs = localConfigRootPath + "/" + platform + "/" + serverAsset.LocalPath; if (!File.Exists(fs)) { list.Add(serverAsset); } } } } return(list); }
/// <summary> /// 拷贝发布资源 /// </summary> static public void CopyPublishAssetsTo(string targetpath, RuntimePlatform platform) { List <string> blackFile = new List <string>() { "/Build.info", ".manifest" }; //清空目标文件夹 if (Directory.Exists(targetpath)) { Directory.Delete(targetpath, true); } //合并路径 var sourcepath = IPath.Combine(BApplication.DevOpsPublishAssetsPath, BApplication.GetPlatformPath(platform)); targetpath = IPath.Combine(targetpath, BApplication.GetPlatformPath(platform)); //TODO SVN更新资源 //TODO 重写拷贝逻辑 var files = Directory.GetFiles(sourcepath, "*", SearchOption.AllDirectories); foreach (var file in files) { var _f = file.Replace("\\", "/"); var ret = blackFile.Find((blackstr) => _f.EndsWith(blackstr, StringComparison.OrdinalIgnoreCase)); if (ret != null) { // Debug.Log("[黑名单]" + _f); continue; } // var tp = _f.Replace(sourcepath, targetpath); FileHelper.Copy(_f, tp, true); } }
/// <summary> /// 编译DLL /// </summary> static public void BuildDll(string outPath, RuntimePlatform platform, BuildMode mode, bool isShowTips = true) { IsShowTips = isShowTips; if (IsShowTips) { EditorUtility.DisplayProgressBar("编译服务", "准备编译环境...", 0.1f); } try { //生成CSProj EditorApplication.ExecuteMenuItem("Assets/Open C# Project"); } catch { } //准备输出环境 var _outPath = Path.Combine(outPath, BApplication.GetPlatformPath(platform)); try { var path = _outPath + "/Hotfix"; if (Directory.Exists(path)) { Directory.Delete(path, true); } Directory.CreateDirectory(path); } catch (Exception e) { Debug.LogError(e.Message); if (IsShowTips) { EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog("提示", "请手动删除hotfix文件后重试!", "OK"); } return; } if (IsShowTips) { EditorUtility.DisplayProgressBar("编译服务", "开始处理脚本", 0.2f); } #region CS DLL引用搜集处理 List <string> dllFileList = new List <string>(); List <string> csFileList = new List <string>(); //所有宏 defineList = new List <string>(); string[] parseCsprojList = new string[] { "Assembly-CSharp.csproj", "BDFramework.Core.csproj" }; foreach (var csproj in parseCsprojList) { var path = Path.Combine(BApplication.ProjectRoot, csproj); if (!File.Exists(path)) { EditorUtility.DisplayDialog("警告", $"请保证csproj存在:\n {csproj}.\n 请在Preferces/ExternalTools 选择 Generate.csproj文件", "OK"); return; } ParseCsprojFile(path, new List <string>() { }, ref csFileList, ref dllFileList); } //去重 dllFileList = dllFileList.Distinct().ToList(); csFileList = csFileList.Distinct().ToList(); defineList = defineList.Distinct().ToList(); //移除参与分析csproj的dll,因为已经解析 包含在cs foreach (var csproj in parseCsprojList) { var dll = csproj.Replace(".csproj", ".dll"); var idx = dllFileList.FindIndex((d) => d.EndsWith(dll, StringComparison.OrdinalIgnoreCase)); if (idx >= 0) { dllFileList.RemoveAt(idx); //Debug.Log("[Build DLL]剔除:" + dll); } } //宏解析 //移除editor相关宏 for (int i = defineList.Count - 1; i >= 0; i--) { var symbol = defineList[i]; if (symbol.Contains("UNITY_EDITOR")) { defineList.RemoveAt(i); } } //剔除不存的dll //TODO 这里是File 接口mac下有bug 会判断文件不存在 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor) { for (int i = dllFileList.Count - 1; i >= 0; i--) { var dll = dllFileList[i]; if (!File.Exists(dll)) { dllFileList.RemoveAt(i); Debug.Log("剔除:" + dll); } } } #endregion // 热更代码 = 框架部分@hotfix + 游戏逻辑部分@hotfix var baseCs = csFileList.FindAll(f => !f.Contains(STR_HOTFIX) && f.EndsWith(".cs")); //筛选cs //不用ILR binding进行编译base.dll,因为binding本身会因为@hotfix调整容易报错 baseCs = baseCs.Where((cs) => (!cs.Contains("\\ILRuntime\\Binding\\Analysis\\") && !cs.Contains("/ILRuntime/Binding/Analysis/")) || cs.EndsWith("CLRBindings.cs")).ToList(); // var hotfixCs = csFileList.FindAll(f => (f.Contains(STR_HOTFIX) || f.Contains(STR_HALF_HOTFIX)) && f.EndsWith(".cs")); var outHotfixPath = Path.Combine(_outPath, DLLPATH); if (mode == BuildMode.Release) { Build(baseCs, hotfixCs, dllFileList, outHotfixPath); } else if (mode == BuildMode.Debug) { Build(baseCs, hotfixCs, dllFileList, outHotfixPath, true); } GlobalAssetsHelper.GenBasePackageAssetBuildInfo(outPath, platform); }
/// <summary> /// 一键导出 /// </summary> public void OnGUI_OneKeyExprot() { GUILayout.BeginVertical(GUILayout.Width(this.maxSize.x / 2), GUILayout.Height(350)); { GUILayout.Label("资源发布:", EditorGUIHelper.GetFontStyle(Color.red, 15)); EditorGUILayout.HelpBox("版本号采用三段式:0.0.1,前两位可以自定义,最后一位默认自增!\n默认导出地址:Devops/PublishAssets", MessageType.Info); GUILayout.Space(5); // foreach (var sp in BApplication.SupportPlatform) { GUILayout.BeginHorizontal(); { var isHas = selectPlatforms.Contains(sp); //选择 var isSelcet = GUILayout.Toggle(isHas, $"生成{BApplication.GetPlatformPath(sp)}资产", GUILayout.Width(150)); // if (isHas != isSelcet) { if (isSelcet) { selectPlatforms.Add(sp); } else { selectPlatforms.Remove(sp); } } var basePackageBuildInfo = BasePackageAssetsHelper.GetPacakgeBuildInfo(EXPORT_PATH, sp); string setVersionNum = ""; var ret = platformVersionMap.TryGetValue(sp, out setVersionNum); if (!ret) { platformVersionMap[sp] = basePackageBuildInfo.Version; } //根据即将设置信息开始解析 var vs = platformVersionMap[sp].Split('.'); int bigNum = 0; int smallNum = 0; int additiveNum = 0; bigNum = int.Parse(vs[0]); smallNum = int.Parse(vs[1]); additiveNum = int.Parse(vs[2]); //version.info信息 渲染 GUILayout.Label("Ver:", GUILayout.Width(30)); bigNum = EditorGUILayout.IntField(bigNum, GUILayout.Width(20)); GUILayout.Label(".", GUILayout.Width(5)); smallNum = EditorGUILayout.IntField(smallNum, GUILayout.Width(20)); GUILayout.Label(".", GUILayout.Width(5)); GUILayout.Label(additiveNum.ToString(), GUILayout.Width(40)); //保存 设置信息 setVersionNum = string.Format("{0}.{1}.{2}", bigNum, smallNum, additiveNum); //渲染预览信息 GUILayout.Space(10); var newVersion = VersionNumHelper.AddVersionNum(basePackageBuildInfo.Version, setVersionNum); GUILayout.Label($"预览: {basePackageBuildInfo.Version} => {newVersion}"); platformVersionMap[sp] = setVersionNum; } GUILayout.EndHorizontal(); GUILayout.Space(2); } // GUILayout.Space(5); if (GUILayout.Button("一键导出所选平台资产(脚本、美术、表格)", GUILayout.Width(350), GUILayout.Height(30))) { if (isBuilding) { return; } isBuilding = true; //开始 生成资源 foreach (var sp in selectPlatforms) { BuildAssetsTools.BuildAllAssets(sp, EXPORT_PATH, platformVersionMap[sp]); platformVersionMap.Remove(sp); } isBuilding = false; } // if (GUILayout.Button("热更资源转hash(生成服务器配置)", GUILayout.Width(350), GUILayout.Height(30))) { //自动转hash PublishPipelineTools.PublishAssetsToServer(EXPORT_PATH); } GUILayout.Space(20); GUILayout.Label("调试功能:", EditorGUIHelper.LabelH4); GUILayout.BeginHorizontal(); { if (GUILayout.Button("拷贝资源到Streaming", GUILayout.Width(175), GUILayout.Height(30))) { //路径 var source = IPath.Combine(EXPORT_PATH, BApplication.GetRuntimePlatformPath()); var target = IPath.Combine(Application.streamingAssetsPath, BApplication.GetRuntimePlatformPath()); if (Directory.Exists(target)) { Directory.Delete(target, true); } //拷贝 FileHelper.CopyFolderTo(source, target); AssetDatabase.Refresh(); } if (GUILayout.Button("删除Streaming资源", GUILayout.Width(175), GUILayout.Height(30))) { var target = IPath.Combine(Application.streamingAssetsPath, BApplication.GetRuntimePlatformPath()); Directory.Delete(target, true); } } } GUILayout.EndHorizontal(); GUILayout.EndVertical(); }
/// <summary> /// 分析dll生成 /// </summary> /// <param name="platform"></param> /// <param name="dllpath"></param> static private void GenCLRBindingByAnalysis(RuntimePlatform platform = RuntimePlatform.Lumin, string dllpath = "") { if (platform == RuntimePlatform.Lumin) { platform = Application.platform; } //默认读StreammingAssets下面path if (dllpath == "") { dllpath = Application.streamingAssetsPath + "/" + BApplication.GetPlatformPath(platform) + DLLPATH; } //不参与自动绑定的 List <Type> excludeTypes = new List <Type>(); // excludeTypes.AddRange(manualBindingTypes); excludeTypes.AddRange(preBindingTypes); //用新的分析热更dll调用引用来生成绑定代码 var outputPath = "Assets/Code/Game/ILRuntime/Binding/Analysis"; ILRuntimeHelper.LoadHotfix(dllpath, false); BindingCodeGenerator.GenerateBindingCode(ILRuntimeHelper.AppDomain, outputPath); ILRuntimeHelper.Close(); /******************移除已经被绑定的部分****************/ var analysisClrBinding = IPath.Combine(outputPath, "CLRBindings.cs"); var manualPath = "Assets/Code/Game/ILRuntime/Binding/Manual"; var prebindingPath = "Assets/Code/Game/ILRuntime/Binding/PreBinding"; //手动绑定的所有文件 var bindingFs = Directory.GetFiles(manualPath, "*.*").ToList(); if (Directory.Exists(prebindingPath)) { bindingFs.AddRange(Directory.GetFiles(prebindingPath, "*.*")); } for (int i = 0; i < bindingFs.Count; i++) { //删除被手动绑定的文件 var f = IPath.Combine(outputPath, Path.GetFileName(bindingFs[i])); if (f != analysisClrBinding && File.Exists(f)) { File.Delete(f); } bindingFs[i] = Path.GetFileNameWithoutExtension(bindingFs[i]); } var analysisContent = File.ReadAllLines(analysisClrBinding).ToList(); //修改CLRbingding内容 for (int i = analysisContent.Count - 1; i >= 0; i--) { var line = analysisContent[i]; //移除line foreach (var mf in bindingFs) { if (line.Contains(mf + ".Register(app);")) { analysisContent.RemoveAt(i); Debug.Log("移除[已经绑定]:" + line); break; } } } //写入 File.WriteAllLines(analysisClrBinding, analysisContent); //Manual AssetDatabase.Refresh(); }
public override void Build(BuildTarget buildTarget, NodeData nodeData, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <ConnectionData> connectionsToOutput, PerformGraph.Output outputFunc, Action <NodeData, string, float> progressFunc) { #region 保存AssetTypeConfig var asetTypePath = string.Format("{0}/{1}/{2}", BuildingCtx.BuildParams.OutputPath, BApplication.GetPlatformPath(buildTarget), BResources.ART_ASSET_TYPES_PATH); //数据结构保存 AssetTypeConfig at = new AssetTypeConfig() { AssetTypeList = BuildingCtx.AssetTypeList, }; var csv = CsvSerializer.SerializeToString(at); FileHelper.WriteAllText(asetTypePath, csv); Debug.LogFormat("AssetType写入到:{0} \n{1}", asetTypePath, csv); #endregion //BD生命周期触发 BDFrameworkPipelineHelper.OnBeginBuildAssetBundle(BuildingCtx); }
/// <summary> /// 获取资源信息路径 /// </summary> /// <param name="rootPath"></param> /// <param name="platform"></param> /// <returns></returns> static public string GetAssetsInfoPath(string rootPath, RuntimePlatform platform) { return(IPath.Combine(rootPath, BApplication.GetPlatformPath(platform), BResources.ASSETS_INFO_PATH)); }
/// <summary> /// 获取版本配置路径 /// </summary> /// <param name="rootPath"></param> /// <param name="platform"></param> /// <returns></returns> static public string GetServerAssetsVersionInfoPath(string rootPath, RuntimePlatform platform) { return(IPath.Combine(rootPath, BApplication.GetPlatformPath(platform), BResources.SERVER_ASSETS_VERSION_INFO_PATH)); }