Beispiel #1
0
        private static bool BuildPlayer(string notification, BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime, BuildOptions options, string configKey)
        {
            bool success = true;

            // Get build options.
            if (releaseType.developmentBuild)
            {
                options |= BuildOptions.Development;
            }
            if (releaseType.allowDebugging)
            {
                options |= BuildOptions.AllowDebugging;
            }

            // Generate build path.
            string buildPath = GenerateBuildPath(BuildSettings.basicSettings.buildPath, releaseType, platform, architecture, distribution, buildTime);
            string exeName   = string.Format(platform.binaryNameFormat, SanitizeFileName(releaseType.productName));

            // Set defines.
            string defines = GenerateDefaultDefines(releaseType, platform, architecture, distribution);

            PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, defines);

            // Pre-build actions.
            PerformPreBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);

            // Generate BuildConstants.
            BuildConstantsGenerator.Generate(buildTime, BuildSettings.productParameters.lastGeneratedVersion, releaseType, platform, architecture, distribution);

            // Refresh scene list to make sure nothing has been deleted or moved.
            releaseType.sceneList.Refresh();

            // Report build starting.
            BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                               BuildNotification.Category.Notification,
                                                               notification, configKey,
                                                               true, null));

            // Build player.
            FileUtil.DeleteFileOrDirectory(buildPath);
            string error = BuildPipeline.BuildPlayer(releaseType.sceneList.GetSceneList(), Path.Combine(buildPath, exeName), architecture.target, options);

            if (!string.IsNullOrEmpty(error))
            {
                success = false;

                BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                                   BuildNotification.Category.Error,
                                                                   "Build Failed:", configKey.ToString() + "\n" + error,
                                                                   true, null));
            }

            // Post-build actions.
            PerformPostBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);

            return(success);
        }
Beispiel #2
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            showViewOptions  = property.FindPropertyRelative("showViewOptions");
            showConfigs      = property.FindPropertyRelative("showConfigs");
            showBuildInfo    = property.FindPropertyRelative("showBuildInfo");
            hideDisabled     = property.FindPropertyRelative("hideDisabled");
            treeView         = property.FindPropertyRelative("treeView");
            selectedKeyChain = property.FindPropertyRelative("selectedKeyChain");

            EditorGUI.BeginProperty(position, label, property);

            EditorGUILayout.BeginHorizontal();

            show = property.isExpanded;
            UnityBuildGUIUtility.DropdownHeader("Build Configurations", ref show, false, GUILayout.ExpandWidth(true));
            property.isExpanded = show;

            UnityBuildGUIUtility.HelpButton("Parameter-Details#build-configurations");
            EditorGUILayout.EndHorizontal();

            Color defaultBackgroundColor = GUI.backgroundColor;

            if (show)
            {
                EditorGUILayout.BeginVertical(UnityBuildGUIUtility.dropdownContentStyle);

                EditorGUILayout.BeginHorizontal();
                show = showViewOptions.isExpanded;
                UnityBuildGUIUtility.DropdownHeader("View Options", ref show, false, GUILayout.ExpandWidth(true));
                showViewOptions.isExpanded = show;
                EditorGUILayout.EndHorizontal();

                if (show)
                {
                    EditorGUILayout.BeginVertical(UnityBuildGUIUtility.dropdownContentStyle);

                    hideDisabled.boolValue = EditorGUILayout.ToggleLeft("Hide disabled configurations", hideDisabled.boolValue);
                    treeView.boolValue     = EditorGUILayout.ToggleLeft("Show full configurations tree", treeView.boolValue);

                    EditorGUILayout.EndVertical();
                }

                GUILayout.Space(5);
                EditorGUILayout.BeginHorizontal();
                show = showConfigs.isExpanded;
                UnityBuildGUIUtility.DropdownHeader("Configurations", ref show, false, GUILayout.ExpandWidth(true));
                showConfigs.isExpanded = show;
                EditorGUILayout.EndHorizontal();

                if (show)
                {
                    EditorGUILayout.BeginVertical(UnityBuildGUIUtility.dropdownContentStyle);

                    if (BuildSettings.projectConfigurations.configSet.Keys.Count > 0)
                    {
                        BuildReleaseType[] releaseTypes = BuildSettings.releaseTypeList.releaseTypes;
                        for (int i = 0; i < releaseTypes.Length; i++)
                        {
                            string        key    = releaseTypes[i].typeName;
                            Configuration config = BuildSettings.projectConfigurations.configSet[key];
                            DisplayConfigTree(key, config, 0);
                        }
                    }
                    else
                    {
                        EditorGUILayout.HelpBox("No Configuration info. Please add a Release Type.", MessageType.Error);
                    }


                    EditorGUILayout.EndVertical();
                }

                GUILayout.Space(5);
                EditorGUILayout.BeginHorizontal();
                show = showBuildInfo.isExpanded;
                UnityBuildGUIUtility.DropdownHeader("Build Info", ref show, false, GUILayout.ExpandWidth(true));
                showBuildInfo.isExpanded = show;
                EditorGUILayout.EndHorizontal();

                if (show)
                {
                    EditorGUILayout.BeginVertical(UnityBuildGUIUtility.dropdownContentStyle);

                    if (string.IsNullOrEmpty(selectedKeyChain.stringValue))
                    {
                        EditorGUILayout.HelpBox("Click a build configuration above in \"Configurations\" to view full details.", MessageType.Info);
                    }
                    else
                    {
                        BuildReleaseType  releaseType;
                        BuildPlatform     platform;
                        BuildArchitecture arch;
                        BuildDistribution dist;

                        bool parseSuccess = BuildSettings.projectConfigurations.ParseKeychain(selectedKeyChain.stringValue, out releaseType, out platform, out arch, out dist);

                        if (parseSuccess)
                        {
                            string defines = BuildProject.GenerateDefaultDefines(releaseType, platform, arch, dist);

                            EditorGUILayout.LabelField("Misc Info", UnityBuildGUIUtility.midHeaderStyle);
                            EditorGUILayout.LabelField("Defines:");
                            EditorGUILayout.LabelField(defines, EditorStyles.wordWrappedLabel);

                            if (releaseType != null)
                            {
                                EditorGUILayout.LabelField("Release Type", UnityBuildGUIUtility.midHeaderStyle);
                                EditorGUILayout.LabelField("Type Name:\t" + releaseType.typeName);

                                if (!string.IsNullOrEmpty(releaseType.bundleIndentifier))
                                {
                                    EditorGUILayout.LabelField("Bundle Identifier:\t" + releaseType.bundleIndentifier);
                                }

                                EditorGUILayout.LabelField("Product Name:\t" + releaseType.productName);
                            }

                            if (platform != null)
                            {
                                EditorGUILayout.LabelField("Platform", UnityBuildGUIUtility.midHeaderStyle);
                                EditorGUILayout.LabelField("Name:\t\t" + platform.platformName);
                            }

                            if (arch != null)
                            {
                                EditorGUILayout.LabelField("Architecture", UnityBuildGUIUtility.midHeaderStyle);
                                EditorGUILayout.LabelField("Name:\t\t" + arch.name);
                            }

                            if (dist != null)
                            {
                                EditorGUILayout.LabelField("Distribution", UnityBuildGUIUtility.midHeaderStyle);
                                EditorGUILayout.LabelField("Name:\t\t" + dist.distributionName);
                            }

                            GUILayout.Space(20);
                            GUI.backgroundColor = Color.green;
                            if (GUILayout.Button("Build", GUILayout.ExpandWidth(true)))
                            {
                                EditorApplication.delayCall += () =>
                                                               BuildProject.BuildSingle(selectedKeyChain.stringValue);
                            }
                            if (GUILayout.Button("Build and Run", GUILayout.ExpandWidth(true)))
                            {
                                EditorApplication.delayCall += () =>
                                                               BuildProject.BuildSingle(selectedKeyChain.stringValue, BuildOptions.AutoRunPlayer);
                            }

                            EditorGUI.BeginDisabledGroup(!releaseType.developmentBuild);
                            if (GUILayout.Button("Build and Run w/ Profiler", GUILayout.ExpandWidth(true)))
                            {
                                EditorApplication.delayCall += () =>
                                                               BuildProject.BuildSingle(selectedKeyChain.stringValue, BuildOptions.AutoRunPlayer | BuildOptions.ConnectWithProfiler);
                            }
                            EditorGUI.EndDisabledGroup();
                            GUI.backgroundColor = defaultBackgroundColor;

                            if (GUILayout.Button("Refresh BuildConstants and Apply Defines", GUILayout.ExpandWidth(true)))
                            {
                            #if UNITY_5_6_OR_NEWER
                                EditorUserBuildSettings.SwitchActiveBuildTarget(platform.targetGroup, arch.target);
                            #else
                                EditorUserBuildSettings.SwitchActiveBuildTarget(arch.target);
                            #endif
                                PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, defines);
                                BuildConstantsGenerator.Generate(DateTime.Now, BuildSettings.productParameters.lastGeneratedVersion, releaseType, platform, arch, dist);
                            }
                        }
                        else
                        {
                            EditorGUILayout.HelpBox("Could not parse selected configuration. It may no longer be valid due to a changes. Select again.", MessageType.Info);
                        }
                    }

                    EditorGUILayout.EndVertical();
                }

                property.serializedObject.ApplyModifiedProperties();

                EditorGUILayout.EndVertical();
            }

            EditorGUI.EndProperty();
        }
Beispiel #3
0
        private static bool BuildPlayer(string notification, BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime, BuildOptions options, string configKey)
        {
            bool success = true;

            // Get build options.
            if (releaseType.developmentBuild)
            {
                options |= BuildOptions.Development;
            }
            if (releaseType.allowDebugging)
            {
                options |= BuildOptions.AllowDebugging;
            }
            if (releaseType.enableHeadlessMode)
            {
                options |= BuildOptions.EnableHeadlessMode;
            }

            // Generate build path.
            string buildPath = GenerateBuildPath(BuildSettings.basicSettings.buildPath, releaseType, platform, architecture, distribution, buildTime);
            string exeName   = string.Format(platform.binaryNameFormat, SanitizeFileName(releaseType.productName));

            // Save current user defines, and then set target defines.
            string preBuildDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(platform.targetGroup);
            string buildDefines    = GenerateDefaultDefines(releaseType, platform, architecture, distribution);

            buildDefines = MergeDefines(preBuildDefines, buildDefines);

            PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, buildDefines);
            //Debug.Log("Build Defines: " + buildDefines);

            // Set bundle info.
            // Unfortunately, there's not a good way to do this pre-5.6 that doesn't break building w/ batch mode.
#if UNITY_5_6_OR_NEWER
            PlayerSettings.SetApplicationIdentifier(platform.targetGroup, releaseType.bundleIndentifier);
#endif

            // Set product name.
            PlayerSettings.companyName = releaseType.companyName;
            PlayerSettings.productName = releaseType.productName;

            // Apply build variant.
            platform.ApplyVariant();

            // Pre-build actions.
            PerformPreBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);

            // Generate BuildConstants.
            BuildConstantsGenerator.Generate(buildTime, BuildSettings.productParameters.lastGeneratedVersion, releaseType, platform, architecture, distribution);

            // Refresh scene list to make sure nothing has been deleted or moved.
            releaseType.sceneList.Refresh();

            // Report build starting.
            BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                               BuildNotification.Category.Notification,
                                                               notification, configKey,
                                                               true, null));

            // Build player.
            FileUtil.DeleteFileOrDirectory(buildPath);

            string error = "";
#if UNITY_2018_1_OR_NEWER
            UnityEditor.Build.Reporting.BuildReport buildReport = BuildPipeline.BuildPlayer(releaseType.sceneList.GetSceneFileList(), Path.Combine(buildPath, exeName), architecture.target, options);
            if (buildReport.summary.result == UnityEditor.Build.Reporting.BuildResult.Failed)
            {
                error = buildReport.summary.totalErrors + " occurred.";
            }
#else
            error = BuildPipeline.BuildPlayer(releaseType.sceneList.GetSceneFileList(), Path.Combine(buildPath, exeName), architecture.target, options);
#endif
            if (!string.IsNullOrEmpty(error))
            {
                success = false;

                BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                                   BuildNotification.Category.Error,
                                                                   "Build Failed:", configKey.ToString() + "\n" + error,
                                                                   true, null));
            }

            // Post-build actions.
            PerformPostBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);

            // Restore pre-build settings.
            PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, preBuildDefines);

            return(success);
        }
Beispiel #4
0
        private static void PerformBuild(string[] buildConfigs, BuildOptions options = BuildOptions.None)
        {
            int successCount = 0;
            int failCount    = 0;

            // Save current script defines, build constants, etc. so we can restore them after build.
            string buildConstantsPath        = BuildConstantsGenerator.FindFile();
            string currentBuildConstantsFile = null;

            if (!string.IsNullOrEmpty(buildConstantsPath))
            {
                currentBuildConstantsFile = FileUtil.GetUniqueTempPathInProject();
                File.Copy(buildConstantsPath, currentBuildConstantsFile);
            }

            DateTime buildTime;

            PerformPreBuild(out buildTime);

            for (int i = 0; i < buildConfigs.Length; i++)
            {
                BuildReleaseType  releaseType;
                BuildPlatform     platform;
                BuildArchitecture arch;
                BuildDistribution dist;
                string            configKey = buildConfigs[i];

                // Parse build config and perform build.
                string notification = string.Format("Building ({0}/{1}): ", i + 1, buildConfigs.Length);
                BuildSettings.projectConfigurations.ParseKeychain(configKey, out releaseType, out platform, out arch, out dist);
                bool success = BuildPlayer(notification, releaseType, platform, arch, dist, buildTime, options, configKey);

                if (success)
                {
                    ++successCount;
                }
                else
                {
                    ++failCount;
                }
            }

            PerformPostBuild();

            // Restore editor status.
            if (!string.IsNullOrEmpty(buildConstantsPath))
            {
                File.Copy(currentBuildConstantsFile, buildConstantsPath, true);
                File.Delete(currentBuildConstantsFile);
            }

            // Report success/failure.
            StringBuilder sb = new StringBuilder();

            if (failCount == 0)
            {
                sb.AppendFormat("{0} successful build{1}. No failures. ✔️",
                                successCount, successCount > 1 ? "s" : "");
            }
            else if (successCount == 0)
            {
                sb.AppendFormat("No successful builds. {0} failure{1}. ✖️",
                                failCount, failCount > 1 ? "s" : "");
            }
            else
            {
                sb.AppendFormat("{0} successful build{1}. {2} failure{3}.",
                                successCount, successCount > 1 ? "s" : "",
                                failCount, failCount > 1 ? "s" : "");
            }
            BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                               BuildNotification.Category.Notification,
                                                               "Build Complete.", sb.ToString(),
                                                               true, null));

            // Open output folder if option is enabled.
            if (BuildSettings.basicSettings.openFolderPostBuild)
            {
                System.Diagnostics.Process.Start(BuildSettings.basicSettings.baseBuildFolder);
            }
        }
Beispiel #5
0
        private static bool BuildPlayer(string notification, BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime, BuildOptions options, string configKey)
        {
            bool success = true;

            // Get build options.获取生成选项。
            if (releaseType.developmentBuild)
            {
                options |= BuildOptions.Development;
            }
            if (releaseType.allowDebugging)
            {
                options |= BuildOptions.AllowDebugging;
            }
            if (releaseType.enableHeadlessMode)
            {
                options |= BuildOptions.EnableHeadlessMode;
            }

            // Generate build path.生成生成路径。
            string buildPath = GenerateBuildPath(BuildSettings.basicSettings.buildPath, releaseType, platform, architecture, distribution, buildTime);
            string binName   = string.Format(architecture.binaryNameFormat, SanitizeFileName(releaseType.productName));

            // Save current user defines, and then set target defines.保存当前用户定义,然后设置目标定义。
            string preBuildDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(platform.targetGroup);
            string buildDefines    = GenerateDefaultDefines(releaseType, platform, architecture, distribution);

            buildDefines = MergeDefines(preBuildDefines, buildDefines);

            PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, buildDefines);
            //Debug.Log("Build Defines: " + buildDefines);

            // Save current player settings, and then set target settings.保存当前播放机设置,然后设置目标设置。
            string preBuildCompanyName = PlayerSettings.companyName;
            string preBuildProductName = PlayerSettings.productName;

            PlayerSettings.companyName = releaseType.companyName;
            PlayerSettings.productName = releaseType.productName;

            // Set bundle info.设置捆绑信息。
            // Unfortunately, there's not a good way to do this pre-5.6 that doesn't break building w/ batch mode.不幸的是,在5.6之前没有一个好的方法可以不破坏构建w/batch模式。
#if UNITY_5_6_OR_NEWER
            string preBuildBundleIdentifier = PlayerSettings.GetApplicationIdentifier(platform.targetGroup);
            PlayerSettings.SetApplicationIdentifier(platform.targetGroup, releaseType.bundleIndentifier);
#endif

            // Apply build variant.应用生成变量。
            platform.ApplyVariant();

            // Pre-build actions.预构建操作。
            PerformPreBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);

            // Generate BuildConstants.生成生成常量。
            BuildConstantsGenerator.Generate(buildTime, BuildSettings.productParameters.lastGeneratedVersion, releaseType, platform, architecture, distribution);

            // Refresh scene list to make sure nothing has been deleted or moved.刷新场景列表以确保未删除或移动任何内容。
            releaseType.sceneList.Refresh();

            // Report build starting.发布生成开始。
            BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                               BuildNotification.Category.Notification,
                                                               notification, configKey,
                                                               true, null));

            // Build player.
            FileUtil.DeleteFileOrDirectory(buildPath);

            string error = "";
#if UNITY_2018_1_OR_NEWER
            //    string[] levels = BuildInfomation.levels;
            /////   Debug.Log("这里才开始生成");

            //string parth = BuildInfomation. Pathlevels+"/Test.exe";

            //    string[]levels = new string[] { "Assets/Scenes/2.unity" };
            string[] levels = BuildInfomation.levels;
            ///\   Debug.Log("这里才开始生成");

            string parth = BuildInfomation.Pathlevels;
            Debug.Log(parth);

            //  Debug.Log("这里才开始生成---"+ BuildInfomation.levels[0].ToString()+"---"+ parth);
            //  Debug.Log(releaseType.sceneList.GetSceneFileList() + "  --AAA--  " + Path.Combine(buildPath, binName)  );
            //  UnityEditor.Build.Reporting.BuildReport buildReport = BuildPipeline.BuildPlayer(levels, @"C:/Users/YNHol/Desktop/00000000000000/Scenes3/Test.exe", BuildTarget.StandaloneWindows, BuildOptions.None);
            UnityEditor.Build.Reporting.BuildReport buildReport = BuildPipeline.BuildPlayer(levels, parth, BuildTarget.WebGL, BuildOptions.None);
            // UnityEditor.Build.Reporting.BuildReport buildReport = BuildPipeline.BuildPlayer(releaseType.sceneList.GetSceneFileList(), Path.Combine(buildPath, binName), architecture.target, options);
            //   Debug.Log(levels[0].ToString() + "__生产___" + parth); ;
            foreach (var item in releaseType.sceneList.GetSceneFileList())
            {
                Debug.Log(item);
            }
            //  Debug.Log("这里生成开始完毕");
            if (buildReport.summary.result == UnityEditor.Build.Reporting.BuildResult.Failed)
            {
                error = buildReport.summary.totalErrors + " occurred.";
            }
#else
            error = BuildPipeline.BuildPlayer(releaseType.sceneList.GetSceneFileList(), Path.Combine(buildPath, binName), architecture.target, options);
#endif
            if (!string.IsNullOrEmpty(error))
            {
                success = false;

                BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                                   BuildNotification.Category.Error,
                                                                   "Build Failed:", configKey.ToString() + "\n" + error,
                                                                   true, null));
            }

            // Post-build actions.
            PerformPostBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);

            // Restore pre-build settings.
            PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, preBuildDefines);
            PlayerSettings.companyName = preBuildCompanyName;
            PlayerSettings.productName = preBuildProductName;

#if UNITY_5_6_OR_NEWER
            PlayerSettings.SetApplicationIdentifier(platform.targetGroup, preBuildBundleIdentifier);
#endif
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            Build_Over_Num++;
            Debug.Log("这里是北京时间:" + System.DateTime.Now + "  完成了___ " + Build_Over_Num + " ___个");

            if (Build_Over_Num < File.ReadAllLines(Application.dataPath + "/Pathlevels.txt", Encoding.Default).Length)
            {
                BuildInfomation.Pathlevels = File.ReadAllLines(Application.dataPath + "/Pathlevels.txt", Encoding.Default)[Build_Over_Num];
                BuildInfomation.levels     = new string[] { File.ReadAllLines(Application.dataPath + "/levels.txt", Encoding.Default)[Build_Over_Num] };
                BuildProject.BuildAll();
            }
            else
            {
                Debug.Log("这里是北京时间:" + System.DateTime.Now + "  全部完成! " + Build_Over_Num + "个");
                Build_Over_Num = 0;
            }

            return(success);
        }
Beispiel #6
0
        /// <summary>
        /// 执行生成
        /// </summary>
        /// <param 生成配置="buildConfigs"></param>
        /// <param 生成选项="options"></param>
        private static void PerformBuild(string[] buildConfigs, BuildOptions options = BuildOptions.None)
        {
            int successCount = 0;
            int failCount    = 0;

            // Save current script defines, build constants, etc. so we can restore them after build.保存当前脚本定义、生成常量等,以便我们可以在生成后还原它们。
            string buildConstantsPath        = BuildConstantsGenerator.FindFile(); //生成常量路径
            string currentBuildConstantsFile = null;                               //当前生成常量文件

            if (!string.IsNullOrEmpty(buildConstantsPath))
            {
                currentBuildConstantsFile = FileUtil.GetUniqueTempPathInProject();
                File.Copy(buildConstantsPath, currentBuildConstantsFile);
            }

            DateTime buildTime;//时间

            PerformPreBuild(out buildTime);
            Debug.Log("+++++++" + buildTime);
            for (int i = 0; i < buildConfigs.Length; i++)      //生成配置
            {
                BuildReleaseType releaseType;                  //生成发布类型
                //  BuildReleaseType releaseType = BuildReleaseType.ReferenceEquals.;//生成发布类型
                BuildPlatform     platform;                    //平台
                BuildArchitecture arch;                        //体系结构
                BuildDistribution dist;                        //分发
                string            configKey = buildConfigs[i]; //配置键

                // Parse build config and perform build.//分析生成配置并执行生成。
                string notification = string.Format("Building ({0}/{1}): ", i + 1, buildConfigs.Length);//通知
                BuildSettings.projectConfigurations.ParseKeychain(configKey, out releaseType, out platform, out arch, out dist);
                Debug.Log("scccc");
                // BuildPlayer(notification, releaseType, platform, arch, dist, buildTime, options, configKey);
                bool success = BuildPlayer(notification, releaseType, platform, arch, dist, buildTime, options, configKey);

                if (success)
                {
                    ++successCount;
                }
                else
                {
                    ++failCount;
                }
            }

            PerformPostBuild();

            // Restore editor status.还原编辑器状态。
            if (!string.IsNullOrEmpty(buildConstantsPath))
            {
                File.Copy(currentBuildConstantsFile, buildConstantsPath, true);
                File.Delete(currentBuildConstantsFile);
            }

            // 报告成功/失败。
            StringBuilder sb = new StringBuilder();

            if (failCount == 0)
            {
                sb.AppendFormat("{0} successful build{1}. No failures. ✔️",
                                successCount, successCount > 1 ? "s" : "");
            }
            else if (successCount == 0)
            {
                sb.AppendFormat("No successful builds. {0} failure{1}. ✖️",
                                failCount, failCount > 1 ? "s" : "");
            }
            else
            {
                sb.AppendFormat("{0} successful build{1}. {2} failure{3}.",
                                successCount, successCount > 1 ? "s" : "",
                                failCount, failCount > 1 ? "s" : "");
            }
            BuildNotificationList.instance.AddNotification(new BuildNotification(
                                                               BuildNotification.Category.Notification,
                                                               "Build Complete.", sb.ToString(),
                                                               true, null));

            // Open output folder if option is enabled.如果选项已启用,请打开输出文件夹。
            if (BuildSettings.basicSettings.openFolderPostBuild)
            {
                ///开路径的方法先不要了
                // System.Diagnostics.Process.Start(BuildSettings.basicSettings.baseBuildFolder);
            }
        }