首次提交

This commit is contained in:
Bob.Song
2026-03-05 18:07:55 +08:00
commit e125bb869e
4534 changed files with 563920 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fbc716d15a94418194d49806f957e327
timeCreated: 1735888291

View File

@@ -0,0 +1,20 @@
using System;
namespace NBF
{
[AttributeUsage(AttributeTargets.Class)]
public class BuildTaskInfoAttribute : Attribute
{
public string Name;
public int Id;
public bool Visable;
public BuildTaskInfoAttribute(int id, string name, bool visable = true)
{
Id = id;
Name = name;
Visable = visable;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 41d2cb56d8994cc6ae893a33f19b3e76
timeCreated: 1735888293

View File

@@ -0,0 +1,10 @@
namespace NBF
{
public class BuildContext
{
/// <summary>
/// 版本号
/// </summary>
public string Ver;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9a97905bd3c747f9ba3c6d1df484568c
timeCreated: 1735888273

View File

@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NBC.Asset.Editor;
using UnityEditor;
using Debug = UnityEngine.Debug;
namespace NBF
{
/// <summary>
/// 打包器
/// </summary>
public class Builder
{
/// <summary>
/// 任务id对应的类型
/// </summary>
private static readonly Dictionary<int, Type> _buildTaskTypes = new Dictionary<int, Type>();
/// <summary>
/// 任务配置信息
/// </summary>
public static readonly List<BuildTaskInfoAttribute> BuildTaskInfo = new List<BuildTaskInfoAttribute>();
[InitializeOnLoadMethod]
private static void OnInitialize()
{
FindTasks();
}
private static void FindTasks()
{
var types = EditUtil.FindAllSubclass<BaseBuildTask>();
foreach (var t in types)
{
var attributes = t.GetCustomAttributes(typeof(BuildTaskInfoAttribute), true);
foreach (var attribute in attributes)
{
if (attribute is BuildTaskInfoAttribute idAttribute && idAttribute.Id > 0)
{
_buildTaskTypes[idAttribute.Id] = t;
BuildTaskInfo.Add(idAttribute);
}
}
}
BuildTaskInfo.Sort((a, b) => a.Id - b.Id);
}
private static Type GetTaskType(int id)
{
return _buildTaskTypes.GetValueOrDefault(id);
}
#region
/// <summary>
/// 供cmd调用的打包接口
/// </summary>
/// <exception cref="Exception"></exception>
public static void RunBuild()
{
var ver = string.Empty;
var ding = 0;
List<int> ids = new List<int>();
List<string> systemValue = new List<string>(Environment.GetCommandLineArgs());
foreach (var str in systemValue)
{
var arr = str.Split("=");
if (arr.Length > 1)
{
var key = arr[0];
var value = arr[1];
if (key == "v")
{
ver = value;
}
else if (key == "ids")
{
var idArr = value.Split(',');
if (idArr.Length > 0)
{
foreach (var id in idArr)
{
if (int.TryParse(id, out var i) && i > 0)
{
ids.Add(i);
}
}
}
}
}
}
if (string.IsNullOrEmpty(ver) || ids.Count < 1)
{
throw new Exception("参数错误");
}
BuildContext buildContext = new BuildContext
{
Ver = ver
};
RunBuildTasks(buildContext, ids.ToArray());
}
public static void RunBuildTasks(BuildContext buildContext, params int[] ids)
{
Debug.Log("开始执行构建任务");
List<Type> types = ids.Select(GetTaskType).Where(type => type != null).ToList();
if (types.Count < 1)
{
throw new Exception("task id error!");
}
List<BaseBuildTask> buildTasks = new List<BaseBuildTask>();
foreach (var type in types)
{
if (Activator.CreateInstance(type) is BaseBuildTask task)
{
buildTasks.Add(task);
}
}
foreach (var task in buildTasks)
{
var sw = new Stopwatch();
sw.Start();
task.Run(buildContext);
sw.Stop();
Debug.Log($"Run 任务={task.GetType().Name} time={sw.ElapsedMilliseconds / 1000f}s");
}
}
#endregion
public static BuildTargetGroup GetTargetGroup()
{
BuildTarget activeTarget = EditorUserBuildSettings.activeBuildTarget;
var targetGroup = BuildTargetGroup.Unknown;
if (activeTarget == BuildTarget.StandaloneWindows || activeTarget == BuildTarget.StandaloneWindows64)
{
targetGroup = BuildTargetGroup.Standalone;
}
else if (activeTarget == BuildTarget.Android)
{
targetGroup = BuildTargetGroup.Android;
}
else if (activeTarget == BuildTarget.iOS)
{
targetGroup = BuildTargetGroup.iOS;
}
return targetGroup;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a11d1aa017534b6195db306f958f5257
timeCreated: 1735888155

View File

@@ -0,0 +1,170 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace NBF
{
public class BuilderWindow : EditorWindow
{
public const int Width = 400;
public const int Height = 645;
[MenuItem("构建/打开构建面板", false, 9)]
public static void ShowWindow()
{
BuilderWindow wnd = GetWindow<BuilderWindow>("APP打包器", true);
wnd.minSize = new Vector2(Width, Height);
}
#region
private GUIStyle _styleTitleSmall;
private GUIStyle StyleTitleSmall
{
get
{
if (_styleTitleSmall == null)
{
_styleTitleSmall = new GUIStyle(EditorStyles.label)
{
fontStyle = FontStyle.Bold,
fontSize = 12
};
}
return _styleTitleSmall;
}
}
#endregion
private readonly HashSet<int> _selectTaskId = new HashSet<int>();
private string Ver;
protected void OnEnable()
{
Ver = PlayerSettings.bundleVersion;
_selectTaskId.Clear();
}
protected void OnGUI()
{
EditorGUILayout.Space();
DrawMenu();
ShowTitle($"环境选择");
Ver = EditorGUILayout.TextField("打包版本号", Ver);
ShowTitle("任务列表");
var tasks = Builder.BuildTaskInfo;
foreach (var task in tasks)
{
var select = _selectTaskId.Contains(task.Id);
GUI.color = select ? Color.white : Color.grey;
if (task.Visable)
{
//复选框
var s = EditorGUILayout.Toggle(task.Name, select, GUILayout.Height(20));
if (s)
{
_selectTaskId.Add(task.Id);
}
else
{
_selectTaskId.Remove(task.Id);
}
}
}
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
GUI.color = Color.white;
if (GUILayout.Button("执行打包", GUILayout.Height(45)))
{
Run();
}
}
private void Run(bool distributed = false, bool cloud = false)
{
var ids = _selectTaskId.ToArray();
if (!cloud)
{
BuildContext buildContext = new BuildContext
{
Ver = Ver,
};
Builder.RunBuildTasks(buildContext, ids);
}
else
{
Debug.LogError("远端构建暂未完成==");
}
}
private void DrawMenu()
{
ShowTitle("快速选中");
GUILayout.BeginHorizontal();
if (GUILayout.Button("提审包", GUILayout.Height(30)))
{
SelectAll();
}
if (GUILayout.Button("自测包", GUILayout.Height(30)))
{
SelectSelfTest();
}
if (GUILayout.Button("取消选择", GUILayout.Height(30)))
{
_selectTaskId.Clear();
}
EditorGUILayout.EndHorizontal();
}
#region
private void SelectAll()
{
_selectTaskId.Clear();
foreach (var task in Builder.BuildTaskInfo)
{
_selectTaskId.Add(task.Id);
}
}
private void SelectSelfTest()
{
_selectTaskId.Clear();
_selectTaskId.Add(BuildTaskId.Excel);
_selectTaskId.Add(BuildTaskId.AB);
_selectTaskId.Add(BuildTaskId.App);
_selectTaskId.Add(BuildTaskId.CopyShare);
}
#endregion
private void ShowTitle(string str)
{
EditorGUILayout.Space();
GUILayout.Label(str, StyleTitleSmall);
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
}
private bool HasSelectTask(int id)
{
return _selectTaskId.Contains(id);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 89fa3eb5ebcd4df692e9a2a19815ae8b
timeCreated: 1735890628

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 153e12cafc9f4d86bbde017079fa5bf5
timeCreated: 1735888397

View File

@@ -0,0 +1,13 @@
namespace NBF
{
public class BuildTaskId
{
public const int Excel = 1;
public const int AB = 2;
public const int App = 3;
public const int CopyShare = 4;
public const int DingTalkNotice = 5;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c621b4acadc844a6ae65dc15916355fc
timeCreated: 1735888399

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c5bff86240194f81882a09430e3e9523
timeCreated: 1735888252

View File

@@ -0,0 +1,7 @@
namespace NBF
{
public abstract class BaseBuildTask
{
public abstract void Run(BuildContext context);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2d1fa1e3836b449ea0f81c0fa1ca7246
timeCreated: 1735888255

View File

@@ -0,0 +1,42 @@
using System.IO;
using UnityEditor;
using UnityEngine;
namespace NBF
{
/// <summary>
/// 打包ab
/// </summary>
[BuildTaskInfo(BuildTaskId.AB, "打包AB")]
public class BuildABTask : BaseBuildTask
{
public override void Run(BuildContext context)
{
if (context.Ver != PlayerSettings.bundleVersion)
{
PlayerSettings.bundleVersion = context.Ver;
}
DeleteStreamingAssetsBundleCache();
NBC.Asset.Editor.Builder.Build();
// Builder.Build();
}
void DeleteStreamingAssetsBundleCache()
{
var mainFolder = Path.Combine(Application.streamingAssetsPath, "main").Replace("\\", "/");
if (Directory.Exists(mainFolder))
Directory.Delete(mainFolder, true);
string[] files = Directory.GetFiles(Application.streamingAssetsPath);
foreach (string file in files)
{
var filePath = file.Replace("\\", "/");
string fileName = Path.GetFileName(filePath);
if (fileName.Contains("packages_") || fileName.Contains("version"))
File.Delete(filePath);
}
AssetDatabase.Refresh();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2acde0d91b8b47ad8abdd6febd62232c
timeCreated: 1735888685

View File

@@ -0,0 +1,121 @@
using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace NBF
{
/// <summary>
/// 打包app
/// </summary>
[BuildTaskInfo(BuildTaskId.App, "打包App")]
public class BuildAppTask : BaseBuildTask
{
public static readonly string AppInfoPath = Application.dataPath + "/Scripts/Def/AppInfo.cs";
public static readonly string ProjectDir = Directory.GetParent(Application.dataPath)?.ToString();
private BuildContext _context;
public override void Run(BuildContext context)
{
_context = context;
ChangeAppInfo();
BuildAppByPath();
}
/// <summary>
/// 修改打包脚本信息
/// </summary>
private void ChangeAppInfo()
{
if (!File.Exists(AppInfoPath))
{
Debug.LogError("app info 脚本路径错误");
return;
}
EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
if (_context.Ver != PlayerSettings.bundleVersion)
{
PlayerSettings.bundleVersion = _context.Ver;
}
var change = false;
var lines = File.ReadAllLines(AppInfoPath);
for (var i = 0; i < lines.Length; i++)
{
var str = lines[i];
if (str.Contains("string Code"))
{
if (!str.Contains(_context.Ver))
{
lines[i] = $"\t\tpublic const string Code = \"{_context.Ver}\";";
change = true;
}
}
}
if (change)
{
File.WriteAllLines(AppInfoPath, lines);
AssetDatabase.Refresh();
}
}
private void BuildAppByPath()
{
// 设置打包的输出路径
string outputPath = $"{ProjectDir}/Release";
string location =
$"{outputPath}/{_context.Ver}/Fishing.exe";
BuildTarget activeTarget = EditorUserBuildSettings.activeBuildTarget;
switch (activeTarget)
{
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
case BuildTarget.Android:
case BuildTarget.iOS:
EditorSettings.spritePackerMode = SpritePackerMode.AlwaysOnAtlas;
PlayerSettings.gcIncremental = true;
break;
}
var targetGroup = Builder.GetTargetGroup();
if (targetGroup == BuildTargetGroup.Unknown)
{
Debug.LogError("不支持的平台");
return;
}
// 读取 Build Settings 中 “Scenes In Build” 勾选的场景
var scenes = EditorBuildSettings.scenes
.Where(s => s.enabled)
.Select(s => s.path)
.ToArray();
var buildOptions = BuildOptions.CompressWithLz4;
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions()
{
scenes = scenes, //new[] { "Assets/Scenes/StartUp.unity" }, //Assets/Scenes/StartUp.unity
locationPathName = location,
options = buildOptions,
target = activeTarget,
targetGroup = targetGroup,
};
var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
{
Debug.LogError("打包失败");
return;
}
#if UNITY_EDITOR
Application.OpenURL($"file:///{outputPath}");
#endif
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2039f10c99ae4fa18259e438203cc78c
timeCreated: 1735889001

View File

@@ -0,0 +1,14 @@
namespace NBF
{
/// <summary>
/// 导表
/// </summary>
[BuildTaskInfo(BuildTaskId.Excel, "导出Excel表")]
public class BuildExcelTask : BaseBuildTask
{
public override void Run(BuildContext context)
{
// ExcelToJsonWindow.GenConfig(false);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 241caaeb76c54700bc0da1f73179fcf4
timeCreated: 1735888813