266 lines
9.8 KiB
C#
266 lines
9.8 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Reflection;
|
|||
|
using Sirenix.OdinInspector;
|
|||
|
using Sirenix.OdinInspector.Editor;
|
|||
|
using UnityEditor;
|
|||
|
using UnityEditor.Build.Reporting;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEngine.SceneManagement;
|
|||
|
using Debug = UnityEngine.Debug;
|
|||
|
|
|||
|
namespace HK.Editor
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 构建工具
|
|||
|
/// 后续考虑搞一个一键打包工具,该打包会执行自动
|
|||
|
/// 生成热更程序集 ——> 生成hybridCLR Aot ——> copy aotDlls ——> yooasset 构建资源 ——> 构建平台包 ——> 完成
|
|||
|
/// </summary>
|
|||
|
public class CustomBuildTool : OdinEditorWindow
|
|||
|
{
|
|||
|
// 定义一个构建目标平台
|
|||
|
enum BuildType
|
|||
|
{
|
|||
|
PC,
|
|||
|
Android,
|
|||
|
WebGL,
|
|||
|
}
|
|||
|
|
|||
|
static string citizenPath = "Plugins/Citizen";
|
|||
|
static string buildFolderPath = "";
|
|||
|
private static string buidRootPath = "Builds";
|
|||
|
|
|||
|
public BuildTargetPlatform platform = BuildTargetPlatform.StandaloneWindows;
|
|||
|
[LabelText("是否使用Citizen打印机")] public bool isCitizenPrinter;
|
|||
|
|
|||
|
public enum BuildTargetPlatform
|
|||
|
{
|
|||
|
StandaloneWindows,
|
|||
|
StandaloneWindows64,
|
|||
|
Android,
|
|||
|
WebGL,
|
|||
|
IOS,
|
|||
|
StandaloneOSX,
|
|||
|
StandaloneLinux64,
|
|||
|
TvOS,
|
|||
|
PS4,
|
|||
|
}
|
|||
|
|
|||
|
[MenuItem("Tool/Build")]
|
|||
|
static void ShowWindow()
|
|||
|
{
|
|||
|
GetWindow<CustomBuildTool>().Show();
|
|||
|
}
|
|||
|
|
|||
|
[Button("打包")]
|
|||
|
void Build()
|
|||
|
{
|
|||
|
BuildTarget target = BuildTarget.NoTarget;
|
|||
|
switch (platform)
|
|||
|
{
|
|||
|
case BuildTargetPlatform.StandaloneWindows:
|
|||
|
target = BuildTarget.StandaloneWindows;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.StandaloneWindows64:
|
|||
|
target = BuildTarget.StandaloneWindows64;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.Android:
|
|||
|
target = BuildTarget.Android;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.WebGL:
|
|||
|
target = BuildTarget.WebGL;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.IOS:
|
|||
|
target = BuildTarget.iOS;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.StandaloneOSX:
|
|||
|
target = BuildTarget.StandaloneOSX;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.StandaloneLinux64:
|
|||
|
target = BuildTarget.StandaloneLinux64;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.TvOS:
|
|||
|
target = BuildTarget.tvOS;
|
|||
|
break;
|
|||
|
case BuildTargetPlatform.PS4:
|
|||
|
target = BuildTarget.PS4;
|
|||
|
break;
|
|||
|
default:
|
|||
|
throw new ArgumentOutOfRangeException();
|
|||
|
}
|
|||
|
|
|||
|
Run(target, GetBuildPath());
|
|||
|
}
|
|||
|
|
|||
|
[Button("打开Build文件夹")]
|
|||
|
void OpenBuildDirectory()
|
|||
|
{
|
|||
|
OpenFolder();
|
|||
|
}
|
|||
|
|
|||
|
[Button("清空所有Build文件夹")]
|
|||
|
void ClearBuildDirectory()
|
|||
|
{
|
|||
|
if (EditorUtility.DisplayDialog("提示", "确认清空所有平台的Build文件夹?", "是", "否"))
|
|||
|
{
|
|||
|
Directory.Delete(buidRootPath, true);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
string GetBuildPath()
|
|||
|
{
|
|||
|
string name = $"{Application.productName}-{DateTime.Now:yy-MM-dd}-v{Application.version}";
|
|||
|
string extension = platform == BuildTargetPlatform.Android ? "apk" :
|
|||
|
platform == BuildTargetPlatform.WebGL ? "html" :
|
|||
|
platform == BuildTargetPlatform.StandaloneWindows ? "exe" :
|
|||
|
platform == BuildTargetPlatform.StandaloneWindows64 ? "exe" : "";
|
|||
|
string dir = $"{buidRootPath}/{platform.ToString()}/v{Application.version}";
|
|||
|
string path = $"{dir}/{name}.{extension}";
|
|||
|
buildFolderPath = dir;
|
|||
|
if (Directory.Exists(dir))
|
|||
|
Directory.Delete(dir, true);
|
|||
|
|
|||
|
Directory.CreateDirectory(dir);
|
|||
|
return path;
|
|||
|
}
|
|||
|
|
|||
|
private void Run(BuildTarget buildTarget, string outputFilePath)
|
|||
|
{
|
|||
|
// 清空一下文件夹的内容,避免某些重叠问题
|
|||
|
if (Directory.Exists(outputFilePath))
|
|||
|
Directory.Delete(outputFilePath, true);
|
|||
|
|
|||
|
switch (buildTarget)
|
|||
|
{
|
|||
|
case BuildTarget.Android:
|
|||
|
ChangeAssetLoadMode(BuildType.Android);
|
|||
|
// Android签名配置示例
|
|||
|
// PlayerSettings.Android.keystoreName = "path/to/keystore";
|
|||
|
// PlayerSettings.Android.keystorePass = "password";
|
|||
|
break;
|
|||
|
case BuildTarget.WebGL:
|
|||
|
ChangeAssetLoadMode(BuildType.WebGL);
|
|||
|
break;
|
|||
|
case BuildTarget.StandaloneWindows:
|
|||
|
ChangeAssetLoadMode(BuildType.PC);
|
|||
|
break;
|
|||
|
case BuildTarget.StandaloneWindows64:
|
|||
|
ChangeAssetLoadMode(BuildType.PC);
|
|||
|
break;
|
|||
|
default:
|
|||
|
throw new ArgumentOutOfRangeException(nameof(buildTarget), buildTarget, null);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// 设置要构建的场景
|
|||
|
string[] scenes = EditorBuildSettings.scenes
|
|||
|
.Where(s => s.enabled)
|
|||
|
.Select(s => s.path)
|
|||
|
.ToArray();
|
|||
|
|
|||
|
// 设置构建选项
|
|||
|
BuildPlayerOptions buildOptions = new BuildPlayerOptions
|
|||
|
{
|
|||
|
scenes = scenes,
|
|||
|
locationPathName = outputFilePath,
|
|||
|
target = buildTarget,
|
|||
|
options = BuildOptions.None // 根据需要设置构建选项,如压缩、包含调试信息等
|
|||
|
};
|
|||
|
|
|||
|
// 开始构建过程
|
|||
|
var buildPlayer = BuildPipeline.BuildPlayer(buildOptions);
|
|||
|
var summary = buildPlayer.summary;
|
|||
|
|
|||
|
if (summary.result == BuildResult.Succeeded)
|
|||
|
{
|
|||
|
if (isCitizenPrinter && (buildTarget == BuildTarget.StandaloneWindows ||
|
|||
|
buildTarget == BuildTarget.StandaloneWindows64))
|
|||
|
{
|
|||
|
CommonHelper.CopyCitizenToBuild(buildFolderPath);
|
|||
|
}
|
|||
|
|
|||
|
OpenFolder();
|
|||
|
Debug.Log($"{buildTarget} 平台构建完成! ");
|
|||
|
}
|
|||
|
else if (summary.result == BuildResult.Cancelled)
|
|||
|
{
|
|||
|
Debug.LogWarning($"{buildTarget} 平台构建取消了! ");
|
|||
|
}
|
|||
|
else if (summary.result == BuildResult.Failed)
|
|||
|
{
|
|||
|
Debug.LogError($"{buildTarget} 平台构建失败了! ");
|
|||
|
}
|
|||
|
else if (summary.result == BuildResult.Unknown)
|
|||
|
{
|
|||
|
Debug.LogError($"{buildTarget} 平台构建 未知状态??! ");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static void OpenFolder()
|
|||
|
{
|
|||
|
// 根据不同的操作系统调用不同的命令来打开文件夹
|
|||
|
string path = Application.dataPath.Replace("Assets", buidRootPath);
|
|||
|
Debug.Log(path);
|
|||
|
Process.Start(path);
|
|||
|
return;
|
|||
|
switch (Application.platform)
|
|||
|
{
|
|||
|
case RuntimePlatform.WindowsEditor:
|
|||
|
Process.Start("explorer.exe", path);
|
|||
|
break;
|
|||
|
case RuntimePlatform.OSXEditor:
|
|||
|
Process.Start("open", path);
|
|||
|
break;
|
|||
|
case RuntimePlatform.LinuxEditor:
|
|||
|
Process.Start("xdg-open", path);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
static void ChangeAssetLoadMode(BuildType buildType)
|
|||
|
{
|
|||
|
// var scene = SceneManager.GetSceneByName("Init");
|
|||
|
// var gameObjects = scene.GetRootGameObjects();
|
|||
|
// foreach (var gameObject in gameObjects)
|
|||
|
// {
|
|||
|
// var components = gameObject.GetComponentsInChildren<Component>();
|
|||
|
// foreach (var component in components)
|
|||
|
// {
|
|||
|
// if (component.GetType() == typeof(Global))
|
|||
|
// {
|
|||
|
// EPlayMode playMode = EPlayMode.EditorSimulateMode;
|
|||
|
// FieldInfo fieldInfo = component.GetType().GetField("playMode", BindingFlags.NonPublic | BindingFlags.Instance);
|
|||
|
//
|
|||
|
// switch (buildType)
|
|||
|
// {
|
|||
|
// case BuildType.PC:
|
|||
|
// playMode = EPlayMode.HostPlayMode;
|
|||
|
// break;
|
|||
|
// case BuildType.Android:
|
|||
|
// playMode = EPlayMode.HostPlayMode;
|
|||
|
// break;
|
|||
|
// case BuildType.WebGL:
|
|||
|
// playMode = EPlayMode.WebPlayMode;
|
|||
|
// break;
|
|||
|
// default:
|
|||
|
// throw new ArgumentOutOfRangeException(nameof(buildType), buildType, null);
|
|||
|
// }
|
|||
|
//
|
|||
|
// if (fieldInfo != null)
|
|||
|
// fieldInfo.SetValue(component, playMode);
|
|||
|
// else
|
|||
|
// Debug.LogError("检查一下,打包出问题了!没找到global");
|
|||
|
//
|
|||
|
// EditorUtility.SetDirty(gameObject);
|
|||
|
//
|
|||
|
// Debug.Log($"资源加载模式自动更改为 {playMode}.");
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|