AlicizaX/Client/Assets/Editor/BuildCLI/AppBuilder/AppBuildHelper.cs
2025-11-18 10:12:40 +08:00

217 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using AlicizaX;
using AlicizaX.Debugger.Runtime;
using AlicizaX.Editor;
using AlicizaX.Framework.Runtime.ABase;
using UnityEditor;
using UnityEngine;
public static class AppBuildHelper
{
/// <summary>
/// 构建 Android 应用
/// </summary>
public static void BuildAndroid(AndroidBuildParameters androidParams, bool showExplorer = false)
{
if (!PreBuildCheck(androidParams))
{
Debug.LogError("Android 构建前检查失败!");
return;
}
// 设置 Android 特定参数
ApplyAndroidSpecificSettings(androidParams);
// 执行通用构建流程
BuildApplication(androidParams, showExplorer);
}
/// <summary>
/// 构建 Standalone 应用 (Windows/Mac/Linux)
/// </summary>
public static void BuildStandalone(StandaloneBuildParameters standaloneParams, bool showExplorer = false)
{
if (!PreBuildCheck(standaloneParams))
{
Debug.LogError("Standalone 构建前检查失败!");
return;
}
// 设置 Standalone 特定参数
ApplyStandaloneSpecificSettings(standaloneParams);
// 执行通用构建流程
BuildApplication(standaloneParams, showExplorer);
}
#region
private static void BuildApplication(IBuildParameters buildParams, bool showExplorer = false)
{
if (!Directory.Exists(buildParams.OutPutPath))
{
Directory.CreateDirectory(buildParams.OutPutPath);
}
PlayerSettings.bundleVersion = buildParams.Version;
Debug.Log($"开始构建应用 - 目标平台: {buildParams.BuildTarget}");
// 生成应用设置
GeneratAppBuilderSetting(buildParams);
Debug.Log("生成 AppBuilderSetting.bytes 完成");
try
{
var options = new BuildPlayerOptions
{
scenes = buildParams.Scenes,
locationPathName = Path.Combine(buildParams.OutPutPath, buildParams.FileName),
target = buildParams.BuildTarget,
options = buildParams.DevelopBuild ? BuildOptions.Development : BuildOptions.None
};
var report = BuildPipeline.BuildPlayer(options);
HandleBuildReport(report);
if (showExplorer && report.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded)
{
DirectoryInfo directoryInfo = Directory.GetParent(report.summary.outputPath);
if (directoryInfo != null)
OpenFolder.Execute(directoryInfo.FullName);
}
}
catch (Exception e)
{
Debug.LogError($"构建过程中发生异常: {e.Message}\n{e.StackTrace}");
}
finally
{
DeleteBuilderSettingInfo();
}
}
private static void ApplyAndroidSpecificSettings(AndroidBuildParameters androidParams)
{
// 设置 Android 平台特定的 PlayerSettings
PlayerSettings.defaultInterfaceOrientation = UIOrientation.LandscapeLeft;
PlayerSettings.Android.minSdkVersion = androidParams.MinSdkVersion;
PlayerSettings.Android.targetSdkVersion = androidParams.TargetSdkVersion;
if (!string.IsNullOrEmpty(androidParams.BundleIdentifier))
{
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, androidParams.BundleIdentifier);
}
PlayerSettings.Android.bundleVersionCode = androidParams.BundleVersionCode;
// 设置纹理压缩格式
EditorUserBuildSettings.androidBuildSubtarget = androidParams.TextureCompression;
Debug.Log($"Android 特定设置应用完成 - MinSDK: {androidParams.MinSdkVersion}, Bundle: {androidParams.BundleIdentifier}");
}
private static void ApplyStandaloneSpecificSettings(StandaloneBuildParameters standaloneParams)
{
// 设置 Standalone 平台特定的 PlayerSettings
PlayerSettings.fullScreenMode = standaloneParams.FullScreenMode;
if (standaloneParams.FullScreenMode == FullScreenMode.Windowed)
{
PlayerSettings.defaultScreenWidth = standaloneParams.DefaultScreenWidth;
PlayerSettings.defaultScreenHeight = standaloneParams.DefaultScreenHeight;
}
PlayerSettings.runInBackground = standaloneParams.RunInBackground;
Debug.Log($"Standalone 特定设置应用完成 - 分辨率: {standaloneParams.DefaultScreenWidth}x{standaloneParams.DefaultScreenHeight}, 全屏: {standaloneParams.FullScreenMode}");
}
private static bool PreBuildCheck(IBuildParameters buildParams)
{
// 检查场景
if (buildParams.Scenes == null || buildParams.Scenes.Length == 0)
{
Debug.LogError("构建场景列表为空!");
return false;
}
foreach (string scenePath in buildParams.Scenes)
{
if (!File.Exists(scenePath))
{
Debug.LogError($"场景文件不存在: {scenePath}");
return false;
}
}
// 检查输出路径
if (string.IsNullOrEmpty(buildParams.OutPutPath))
{
Debug.LogError("输出路径为空!");
return false;
}
// 检查文件名
if (string.IsNullOrEmpty(buildParams.FileName))
{
Debug.LogError("文件名为空!");
return false;
}
return true;
}
public static void GeneratAppBuilderSetting(IBuildParameters buildParameters)
{
const string AppBuilderSettingPath = "Assets/Resources/ModuleDynamicBindInfo.bytes";
ModuleDynamicBindInfo appBuilderSetting = new ModuleDynamicBindInfo();
appBuilderSetting.Language = buildParameters.Language;
appBuilderSetting.DebuggerActiveWindowType = buildParameters.ShowDebugWnd;
appBuilderSetting.ResMode = buildParameters.ResMode;
appBuilderSetting.DecryptionServices = buildParameters.DecryptionServices;
File.WriteAllText(AppBuilderSettingPath, Utility.Json.ToJson(appBuilderSetting));
}
public static void DeleteBuilderSettingInfo()
{
const string AppBuilderSettingPath = "Assets/Resources/ModuleDynamicBindInfo.bytes";
if (File.Exists(AppBuilderSettingPath))
{
File.Delete(AppBuilderSettingPath);
}
}
private static void HandleBuildReport(UnityEditor.Build.Reporting.BuildReport report)
{
if (report.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded)
{
Debug.Log($"构建完成: {report.summary.outputPath}");
}
else
{
#if UNITY_2023_1_OR_NEWER
Debug.LogError(report.SummarizeErrors());
#else
var errors = new List<string>();
foreach (var step in report.steps)
{
foreach (var msg in step.messages)
{
if (msg.type == LogType.Error || msg.type == LogType.Exception)
{
errors.Add($"[Step: {step.name}] {msg.content}");
}
}
}
Debug.LogError($"构建失败,错误信息:\n{string.Join("\n", errors)}");
#endif
}
}
#endregion
}