Esempio n. 1
0
        /// <summary>
        /// 生成sqlite
        /// 默认导出到当前平台目录下
        /// </summary>
        /// <param name="ouptputPath">自定义路径</param>
        public static void AllExcel2SQLite(string ouptputPath, RuntimePlatform platform, DBType dbType = DBType.Local)
        {
            //触发bd环境周期
            BDFrameworkPipelineHelper.OnBeginBuildSqlite();
            var xlslFiles = ExcelEditorTools.GetAllExcelFiles();

            switch (dbType)
            {
            case DBType.Local:
                SqliteLoder.LoadLocalDBOnEditor(ouptputPath, platform);
                break;

            case DBType.Server:
                SqliteLoder.LoadServerDBOnEditor(ouptputPath, platform);
                break;
            }

            {
                foreach (var f in xlslFiles)
                {
                    try
                    {
                        Excel2SQLite(f, dbType);
                    }
                    catch (Exception e)
                    {
                        Debug.LogError("导表失败:" + f);
                        EditorUtility.ClearProgressBar();
                    }
                }
            }
            SqliteLoder.Close();
            //
            EditorUtility.ClearProgressBar();
            //触发bd环境周期
            BDFrameworkPipelineHelper.OnEndBuildSqlite(ouptputPath);
            BasePackageAssetsHelper.GenBasePackageAssetBuildInfo(ouptputPath, platform);
            Debug.Log("导出Sqlite完成!");
        }
Esempio n. 2
0
        /// <summary>

        #region 启动热更逻辑

        /// <summary>
        /// 初始化
        /// 修改版本,让这个启动逻辑由使用者自行处理
        /// </summary>
        /// <param name="mainProjectTypes">Editor模式下,UPM隔离了DLL需要手动传入</param>
        /// <param name="GameId">单游戏更新启动不需要id,多游戏更新需要id号</param>
        public void Launch(Type[] mainProjectTypes, Action <bool> clrBindingAction, string gameId = "default")
        {
            BDebug.Log("【Launch】Persistent:" + Application.persistentDataPath);
            BDebug.Log("【Launch】StreamingAsset:" + Application.streamingAssetsPath);
            //主工程启动
            IGameStart mainStart;

            foreach (var type in mainProjectTypes)
            {
                //TODO 这里有可能先访问到 IGamestart的Adaptor
                if (type.IsClass && type.GetInterface(nameof(IGameStart)) != null)
                {
                    BDebug.Log("【Launch】主工程Start! " + type.FullName);
                    mainStart = Activator.CreateInstance(type) as IGameStart;
                    if (mainStart != null)
                    {
                        //注册
                        mainStart.Start();
                        OnUpdate     += mainStart.Update;
                        OnLateUpdate += mainStart.LateUpdate;
                        break;
                    }
                }
            }


            BDebug.Log("【Launch】框架资源版本验证!");
            //开始资源检测
            BasePackageAssetsHelper.CheckBasePackageVersion(BApplication.RuntimePlatform, () =>
            {
                //1.美术目录
                BResources.Init(GameConfig.ArtRoot);
                //2.sql
                SqliteLoder.Init(GameConfig.SQLRoot);
                //3.脚本,这个启动会开启所有的逻辑
                ScriptLoder.Init(GameConfig.CodeRoot, GameConfig.CodeRunMode, mainProjectTypes, clrBindingAction);
            });
        }
        /// <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));
                //输出路径
                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 = BasePackageAssetsHelper.GetPacakgeBuildInfo(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>
        /// 一键导出
        /// </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>
    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);
        }

        BasePackageAssetsHelper.GenBasePackageAssetBuildInfo(outPath, platform);
    }
Esempio n. 6
0
        /// <summary>
        /// 构建所有资源
        /// </summary>
        /// <param name="platform">平台</param>
        /// <param name="outputPath">输出目录</param>
        /// <param name="setNewVersionNum">新版本号</param>
        static public void BuildAllAssets(RuntimePlatform platform, string outputPath, string setNewVersionNum = null)
        {
            var newVersionNum = "";
            //触发事件
            var lastPackageBuildInfo = BasePackageAssetsHelper.GetPacakgeBuildInfo(outputPath, platform);
            var lastVersionNum       = lastPackageBuildInfo.Version;

            //没有指定版本号,则需要触发版本号的实现逻辑
            if (string.IsNullOrEmpty(setNewVersionNum))
            {
                BDFrameworkPipelineHelper.OnBeginBuildAllAssets(platform, outputPath, lastVersionNum, out newVersionNum);
            }

            //项目没有实现提供新的版本号,则内部提供一个版本号
            if (string.IsNullOrEmpty(newVersionNum) || lastVersionNum == newVersionNum)
            {
                //没指定版本号
                if (string.IsNullOrEmpty(setNewVersionNum))
                {
                    newVersionNum = VersionNumHelper.AddVersionNum(lastVersionNum, add: 1);
                }
                //指定版本号
                else
                {
                    newVersionNum = VersionNumHelper.AddVersionNum(lastVersionNum, setNewVersionNum);
                }
            }


            //开始构建资源
            var _outputPath = Path.Combine(outputPath, BApplication.GetPlatformPath(platform));

            if (!Directory.Exists(_outputPath))
            {
                Directory.CreateDirectory(_outputPath);
            }

            //1.编译脚本
            try
            {
                EditorWindow_ScriptBuildDll.RoslynBuild(outputPath, platform, ScriptBuildTools.BuildMode.Release);
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }

            //2.打包表格
            try
            {
                Excel2SQLiteTools.AllExcel2SQLite(outputPath, platform);
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }

            //3.打包资源
            try
            {
                //var config = BDEditorApplication.BDFrameWorkFrameEditorSetting.BuildAssetBundle;
                AssetBundleEditorToolsV2.GenAssetBundle(outputPath, platform);
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }

            //4.生成母包资源信息
            BasePackageAssetsHelper.GenBasePackageAssetBuildInfo(outputPath, platform, version: newVersionNum);

            //5.生成本地Assets.info配置
            //这个必须最后生成!!!!
            //这个必须最后生成!!!!
            //这个必须最后生成!!!!
            var allServerAssetItemList = PublishPipelineTools.GetAssetItemList(outputPath, platform);
            var csv            = CsvSerializer.SerializeToString(allServerAssetItemList);
            var assetsInfoPath = BResources.GetAssetsInfoPath(outputPath, platform);

            FileHelper.WriteAllText(assetsInfoPath, csv);
            //
            Debug.Log($"<color=yellow>{ BApplication.GetPlatformPath(platform)} - 旧版本:{lastPackageBuildInfo.Version} 新版本号:{newVersionNum} </color> ");
            //完成回调通知
            BDFrameworkPipelineHelper.OnEndBuildAllAssets(platform, outputPath, newVersionNum);
        }
        /// <summary>
        /// 打包Asset Bundle
        /// </summary>
        /// <param name="buildAssetsInfo"></param>
        /// <param name="buildParams"></param>
        /// <param name="platform"></param>
        private void BuildAssetBundle(List <AssetBundleItem> assetBundleItemList, BuildAssetsInfo buildAssetsInfo, BuildAssetBundleParams buildParams, RuntimePlatform platform)
        {
            //----------------------------开始设置build ab name-------------------------------
            //根据传进来的资源,设置AB name
            foreach (var buildInfoItem in buildAssetsInfo.AssetDataMaps)
            {
                var assetPath = buildInfoItem.Key;
                var assetData = buildInfoItem.Value;
                //设置ab name
                var ai = GetAssetImporter(assetPath);
                if (ai)
                {
                    ai.SetAssetBundleNameAndVariant(assetData.ABName, null);
                }
            }


            //----------------------------生成AssetBundle-------------------------------
            var    platformOutputPath = Path.Combine(buildParams.OutputPath, BApplication.GetPlatformPath(platform));
            string abOutputPath       = IPath.Combine(platformOutputPath, BResources.ART_ASSET_ROOT_PATH);

            if (!Directory.Exists(abOutputPath))
            {
                Directory.CreateDirectory(abOutputPath);
            }

            //配置
            var buildTarget = BApplication.GetBuildTarget(platform);
            BuildAssetBundleOptions buildOpa =
                BuildAssetBundleOptions.ChunkBasedCompression |                                                                       //压缩
                BuildAssetBundleOptions.DeterministicAssetBundle |                                                                    //保证一致
                //BuildAssetBundleOptions.DisableWriteTypeTree| //关闭TypeTree
                BuildAssetBundleOptions.DisableLoadAssetByFileName | BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension; //关闭使用filename加载

            //关闭TypeTree
            var buildAssetConf = BDEditorApplication.BDFrameWorkFrameEditorSetting?.BuildAssetBundle;

            if (buildAssetConf.IsDisableTypeTree)
            {
                buildOpa |= BuildAssetBundleOptions.DisableWriteTypeTree; //关闭TypeTree
            }


            UnityEditor.BuildPipeline.BuildAssetBundles(abOutputPath, buildOpa, buildTarget);
            Debug.LogFormat("【编译AssetBundle】 output:{0} ,buildTarget:{1}", abOutputPath, buildTarget.ToString());


            //----------------------------清理-------------------------------------
            //1.移除所有的ab
            RemoveAllAssetbundleName();
            //2.删除本地没有的资源
            var allABList = Directory.GetFiles(abOutputPath, "*", SearchOption.AllDirectories).Where((p) => string.IsNullOrEmpty(Path.GetExtension(p)));

            foreach (var abpath in allABList)
            {
                var abname = Path.GetFileName(abpath);
                var ret    = assetBundleItemList.FirstOrDefault((abdata) => abdata.AssetBundlePath == abname);
                if (ret == null)
                {
                    //
                    File.Delete(abpath);
                    File.Delete(abpath + ".manifest");
                    //
                    var path = AssetDatabase.GUIDToAssetPath(abname);
                    Debug.Log("【删除旧ab:】" + abname + "  -  " + path);
                }
            }

            //3.检测本地Assetbundle
            // allAbList = Directory.GetFiles(abOutputPath, "*", SearchOption.AllDirectories);
            // foreach (var abpath in allAbList)
            // {
            //     if (abpath.Contains("."))
            //     {
            //         continue;
            //     }
            //
            //     var depend = AssetDatabase.GetAssetBundleDependencies(abpath,true);
            // }

            BasePackageAssetsHelper.GenBasePackageAssetBuildInfo(buildParams.OutputPath, platform);
        }