341 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author: 白哉
* @Description:
* @Date: 2025年07月25日 星期五 14:07:55
* @Modify:
*/
using System.Linq;
using Logic.Config;
using UnityEditor;
using UnityEngine;
namespace Logic.Editor
{
public class BuildEditor : EditorWindow
{
// 定义宏名称
public const string ENABLE_SPEEDUP = "ENABLE_SPEEDUP";
public const string ENABLE_TRAIN = "ENABLE_TRAIN";
public const string ENABLE_AIMODEL = "ENABLE_AIMODEL";
public const string GAME_AUTO_DEBUG = "GAME_AUTO_DEBUG";
public const string STEAM_CHANNEL = "STEAM_CHANNEL";
public const string USE_INPUT = "USE_INPUT";
private VersionConfig _asset;
private uint _major;
private uint _minor;
private uint _patch;
private int _index;
// 背景
private GUIStyle _redBoxStyle;
private GUIStyle _whiteBoxStyle;
[MenuItem("Tools/打包工具")]
private static void ShowWindow()
{
var window = GetWindow<BuildEditor>();
window.titleContent = new GUIContent("打包工具");
window.Show();
}
private void OnEnable()
{
}
private void OnGUI()
{
if (_redBoxStyle == null)
{
_redBoxStyle = InspectorUtils.GetHelpBoxStyle();
InspectorUtils.AddBorder(_redBoxStyle, new Color(0.5f, 0.4f, 0.4f, 0.6f));
}
if (_whiteBoxStyle == null)
{
_whiteBoxStyle = InspectorUtils.GetHelpBoxStyle();
InspectorUtils.AddBorder(_whiteBoxStyle, new Color(1f, 1f, 1f, 0.2f));
}
if (!_asset)
{
var path = $"Assets/Resources/DataAssets/VersionConfig.asset";
_asset = AssetDatabase.LoadAssetAtPath<VersionConfig>(path);
if (!_asset)
{
_asset = CreateInstance<VersionConfig>();
AssetDatabase.CreateAsset(_asset, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
_asset.Versions = _asset.Versions.OrderByDescending(v => v.VersionId).ToList();
}
EditorGUILayout.BeginHorizontal();
if (InspectorUtils.InspectorButtonWithTextWidth("保存"))
{
EditorUtility.SetDirty(_asset);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
// 所有已存在的版本号主版本号降低至0
if (InspectorUtils.InspectorButtonWithTextWidth("主版本号降低至0"))
{
foreach (var version in _asset.Versions)
{
version.MajorVersion = 0;
_asset.Versions = _asset.Versions.OrderByDescending(v => v.VersionId).ToList();
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b>版本号: </b>");
_major = (uint)EditorGUILayout.IntField((int)_major, GUILayout.Width(20));
_major = (uint)Mathf.Max(1, _major);
_minor = (uint)EditorGUILayout.IntField((int)_minor, GUILayout.Width(20));
_patch = (uint)EditorGUILayout.IntField((int)_patch, GUILayout.Width(20));
var versionId = _major * 10000 + _minor * 100 + _patch;
var desc = $"{_major}.{_minor}.{_patch}";
if (_asset.GetVersionInfo(versionId) != null)
{
InspectorUtils.InspectorTextWidthRich($"<b>已存在版本号{_major}.{_minor}.{_patch}</b>");
}
else
{
if (InspectorUtils.InspectorButtonWithTextWidth($"创建版本号{desc}"))
{
_asset.CreateNewVersion(_major, _minor, _patch);
_asset.Versions = _asset.Versions.OrderByDescending(v => v.VersionId).ToList();
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
if (_asset.Versions.Count == 0) return;
EditorGUILayout.BeginVertical(_redBoxStyle);
InspectorUtils.InspectorTextWidthRich($"<b>版本构建</b>");
var versionList = _asset.Versions.Select(v => $"{v.FullVersion}").ToArray();
_index = Mathf.Clamp(_index, 0, versionList.Length - 1);
_index = EditorGUILayout.Popup(_index, versionList);
var selectedVersion = _asset.Versions[_index];
EditorGUILayout.BeginVertical(_whiteBoxStyle);
InspectorUtils.InspectorTextWidthRich($"<b>版本{selectedVersion.FullVersion}描述: </b>");
selectedVersion.Description = EditorGUILayout.TextArea(selectedVersion.Description, GUILayout.Height(60));
EditorGUILayout.EndVertical();
EditorGUILayout.BeginHorizontal();
#if ENABLE_AIMODEL
InspectorUtils.InspectorTextWidthRich($"<b><color=red>AI模型已开启</color></b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"关闭AI模型")) RemoveDefine(ENABLE_AIMODEL);
#else
InspectorUtils.InspectorTextWidthRich($"<b>AI模型已关闭</b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"开启AI模型")) AddDefine(ENABLE_AIMODEL);
#endif
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
#if ENABLE_TRAIN
InspectorUtils.InspectorTextWidthRich($"<b><color=red>训练模式已开启:</color></b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"关闭训练模式")) RemoveDefine(ENABLE_TRAIN);
#else
InspectorUtils.InspectorTextWidthRich($"<b>训练模式已关闭:</b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"开启训练模式")) AddDefine(ENABLE_TRAIN);
#endif
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
#if ENABLE_SPEEDUP
InspectorUtils.InspectorTextWidthRich($"<b><color=red>加速模式已开启:</color></b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"关闭加速模式")) RemoveDefine(ENABLE_SPEEDUP);
#else
InspectorUtils.InspectorTextWidthRich($"<b>加速模式已关闭:</b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"开启加速模式")) AddDefine(ENABLE_SPEEDUP);
#endif
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
#if GAME_AUTO_DEBUG
InspectorUtils.InspectorTextWidthRich($"<b><color=red>自动战斗已开启:</color></b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"关闭自动战斗")) RemoveDefine(GAME_AUTO_DEBUG);
#else
InspectorUtils.InspectorTextWidthRich($"<b>自动战斗已关闭:</b>");
if (InspectorUtils.InspectorButtonWithTextWidth($"开启自动战斗")) AddDefine(GAME_AUTO_DEBUG);
#endif
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (InspectorUtils.InspectorButtonWithTextWidth($"构建测试包"))
{
AddDefine(STEAM_CHANNEL);
AddDefine(USE_INPUT);
_asset.CurVersionId = selectedVersion.VersionId;
PlayerSettings.productName = $"TOHOTOPIA Demo";
EditorUtility.SetDirty(_asset);
AssetDatabase.SaveAssets();
// 更新Unity版本号
PlayerSettings.bundleVersion = selectedVersion.FullVersion;
// Debug包配置
SetDebugBuildSettings();
// 开始构建
// BuildPipeline.BuildPlayer(GetBuildScenes(),
// $"../Pack/Debug_{selectedVersion.FullVersion}/{Application.productName}.exe",
// BuildTarget.StandaloneWindows64,
// BuildOptions.Development | BuildOptions.AllowDebugging | BuildOptions.ConnectWithProfiler);
EditorUtility.SetDirty(_asset);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
if (InspectorUtils.InspectorButtonWithTextWidth($"构建发布包"))
{
AddDefine(STEAM_CHANNEL);
RemoveDefine(USE_INPUT);
_asset.CurVersionId = selectedVersion.VersionId;
PlayerSettings.productName = $"TOHOTOPIA Demo";
EditorUtility.SetDirty(_asset);
AssetDatabase.SaveAssets();
// 更新Unity版本号
PlayerSettings.bundleVersion = selectedVersion.FullVersion;
// Release包配置
SetReleaseBuildSettings();
// // 开始构建
// BuildPipeline.BuildPlayer(GetBuildScenes(),
// $"../Pack/Release_{selectedVersion.FullVersion}/{Application.productName}.exe",
// BuildTarget.StandaloneWindows64,
// BuildOptions.None);
EditorUtility.SetDirty(_asset);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
private void SetDebugBuildSettings()
{
// 脚本后端
PlayerSettings.SetScriptingBackend(BuildTargetGroup.Standalone, ScriptingImplementation.Mono2x);
// 开发者模式
EditorUserBuildSettings.development = true;
// 允许debug
EditorUserBuildSettings.allowDebugging = true;
// 日志等级
PlayerSettings.SetStackTraceLogType(LogType.Log, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Warning, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Error, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Assert, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Exception, StackTraceLogType.ScriptOnly);
// 开启详细日志
PlayerSettings.usePlayerLog = true;
// 开启深度剖析器
PlayerSettings.enableInternalProfiler = true;
SetObfuscationEnabled(false);
}
private void SetReleaseBuildSettings()
{
// 脚本后端
PlayerSettings.SetScriptingBackend(BuildTargetGroup.Standalone, ScriptingImplementation.IL2CPP);
// 关闭开发者模式
EditorUserBuildSettings.development = false;
// 关闭debug
EditorUserBuildSettings.allowDebugging = false;
// 日志等级(只显示错误和异常)
PlayerSettings.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
PlayerSettings.SetStackTraceLogType(LogType.Warning, StackTraceLogType.None);
PlayerSettings.SetStackTraceLogType(LogType.Error, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Assert, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Exception, StackTraceLogType.ScriptOnly);
// 关闭详细日志
PlayerSettings.usePlayerLog = false;
// 关闭深度剖析器
PlayerSettings.enableInternalProfiler = false;
// 开启OPS混淆
SetObfuscationEnabled(true);
}
private void SetObfuscationEnabled(bool enabled)
{
var trueStr = "Global_Enable_Obfuscation\",\r\n \"Value\" : \"True\"";
var falseStr = "Global_Enable_Obfuscation\",\r\n \"Value\" : \"False\"";
// 获取json文件路径
string jsonPath = "Assets/OPS/Obfuscator/Settings/Obfuscator_Settings.json";
// 读取json文件内容
string jsonContent = System.IO.File.ReadAllText(jsonPath);
if (enabled) jsonContent = jsonContent.Replace(falseStr, trueStr);
else jsonContent = jsonContent.Replace(trueStr, falseStr);
// 保存修改后的json
System.IO.File.WriteAllText(jsonPath, jsonContent);
// 刷新资源
AssetDatabase.Refresh();
}
public void AddDefine(string symbol)
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone);
if (!defines.Contains(symbol))
{
defines = string.IsNullOrEmpty(defines)
? symbol
: defines + ";" + symbol;
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, defines);
}
}
public void RemoveDefine(string symbol)
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone);
if (defines.Contains(symbol))
{
defines = defines.Replace($"{symbol};", "")
.Replace($";{symbol}", "")
.Replace(symbol, "")
.Replace(";;", ";")
.Trim(';');
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, defines);
}
}
public void AddAutoBattle()
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone);
if (!defines.Contains(GAME_AUTO_DEBUG))
{
defines = string.IsNullOrEmpty(defines)
? GAME_AUTO_DEBUG
: defines + ";" + GAME_AUTO_DEBUG;
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, defines);
}
}
public void RemoveAutoBattle()
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone);
if (defines.Contains(GAME_AUTO_DEBUG))
{
defines = defines.Replace($"{GAME_AUTO_DEBUG};", "")
.Replace($";{GAME_AUTO_DEBUG}", "")
.Replace(GAME_AUTO_DEBUG, "")
.Replace(";;", ";")
.Trim(';');
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, defines);
}
}
}
}