AlicizaX/Client/Assets/Scripts/Editor/Build/BuildWindow/AssetBundleBuildTab.cs
2025-03-04 18:40:14 +08:00

242 lines
8.2 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.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using YooAsset;
using YooAsset.Editor;
public class AssetBundleBuildTab : EditorWindowTabBase
{
private BuildTarget _abBuildTarget = BuildTarget.StandaloneWindows64;
private string _outputPath = "Builds/AB";
private string _packageVersion;
private bool _copyAfterBuild;
private string _copyDestination;
private ECompressOption _compressOption = ECompressOption.LZ4;
private EFileNameStyle _fileNameStyle = EFileNameStyle.BundleName_HashName;
private EBuildinFileCopyOption _copyOption = EBuildinFileCopyOption.ClearAndCopyByTags;
private string _copyParams = "Launch";
private bool _enableSharePack = true;
private string _selectedEncryption;
private string _selectedPackage;
private List<string> _encryptionClasses;
private List<string> _buildPackageNames;
internal override void OnEnable()
{
LoadEncryptionClasses();
LoadBuildPackageNames();
GeneratePackageVersion();
}
private void GeneratePackageVersion()
{
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
_packageVersion = DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes;
}
private void LoadEncryptionClasses()
{
_encryptionClasses = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => typeof(IEncryptionServices).IsAssignableFrom(t) && !t.IsAbstract)
.Select(t => t.FullName)
.ToList();
}
private void LoadBuildPackageNames()
{
_buildPackageNames = new List<string>();
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
{
_buildPackageNames.Add(package.PackageName);
}
}
internal override void OnGUI()
{
base.OnGUI();
DrawABBuildTab();
}
private void DrawABBuildTab()
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("AB包构建配置", EditorStyles.boldLabel);
// 基本配置
DrawBuildTarget(ref _abBuildTarget);
DrawPathSelection("输出路径:", ref _outputPath);
DrawPackageVersion();
// 高级配置
EditorGUILayout.Space();
EditorGUILayout.LabelField("高级选项", EditorStyles.boldLabel);
_compressOption = (ECompressOption)EditorGUILayout.EnumPopup("压缩方式:", _compressOption);
_fileNameStyle = (EFileNameStyle)EditorGUILayout.EnumPopup("文件命名风格:", _fileNameStyle);
_copyOption = (EBuildinFileCopyOption)EditorGUILayout.EnumPopup("内置文件拷贝选项:", _copyOption);
_copyParams = EditorGUILayout.TextField("拷贝参数:", _copyParams);
_enableSharePack = EditorGUILayout.Toggle("启用共享打包:", _enableSharePack);
DrawEncryptionSelection();
DrawPackageSelection();
// 拷贝配置
EditorGUILayout.Space();
_copyAfterBuild = EditorGUILayout.BeginToggleGroup("构建后拷贝", _copyAfterBuild);
DrawPathSelection("拷贝目标:", ref _copyDestination);
EditorGUILayout.EndToggleGroup();
// 操作按钮
EditorGUILayout.Space();
if (GUILayout.Button("构建AB包", GUILayout.Height(30)))
{
BuildABPackage();
}
if (GUILayout.Button("构建热更程序集", GUILayout.Height(30)))
{
BuildDLLCommand.BuildAndCopyDlls();
}
}
private void DrawBuildTarget(ref BuildTarget target)
{
target = (BuildTarget)EditorGUILayout.EnumPopup("目标平台:", target);
}
private void DrawPackageVersion()
{
EditorGUILayout.BeginHorizontal();
{
_packageVersion = EditorGUILayout.TextField("版本号:", _packageVersion);
if (GUILayout.Button("生成新版本", GUILayout.Width(100)))
{
GeneratePackageVersion();
}
}
EditorGUILayout.EndHorizontal();
}
private void DrawEncryptionSelection()
{
if (_encryptionClasses == null || _encryptionClasses.Count == 0)
{
EditorGUILayout.HelpBox("未找到加密类实现", MessageType.Info);
return;
}
int selectedIndex = Mathf.Max(0, _encryptionClasses.IndexOf(_selectedEncryption));
selectedIndex = EditorGUILayout.Popup("加密方式:", selectedIndex, _encryptionClasses.ToArray());
_selectedEncryption = _encryptionClasses[selectedIndex];
}
private void DrawPackageSelection()
{
if (_buildPackageNames == null || _buildPackageNames.Count == 0)
{
EditorGUILayout.HelpBox("未找到包", MessageType.Info);
return;
}
int selectedIndex = Mathf.Max(0, _buildPackageNames.IndexOf(_selectedPackage));
selectedIndex = EditorGUILayout.Popup("Package:", selectedIndex, _buildPackageNames.ToArray());
_selectedPackage = _buildPackageNames[selectedIndex];
}
private void BuildABPackage()
{
try
{
var parameters = new ScriptableBuildParameters
{
BuildOutputRoot = _outputPath,
BuildTarget = _abBuildTarget,
PackageName = _selectedPackage,
BuildBundleType = (int)EBuildBundleType.AssetBundle,
BuildPipeline = EBuildPipeline.ScriptableBuildPipeline.ToString(),
BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(),
PackageVersion = _packageVersion,
CompressOption = _compressOption,
FileNameStyle = _fileNameStyle,
VerifyBuildingResult = true,
ClearBuildCacheFiles = false,
BuildinFileCopyOption = _copyOption,
BuildinFileCopyParams = _copyParams,
EnableSharePackRule = _enableSharePack,
EncryptionServices = CreateEncryptionInstance()
};
ScriptableBuildPipeline pipeline = new ScriptableBuildPipeline();
var report = pipeline.Run(parameters, true);
if (report.Success)
{
BuildUpdateData(_packageVersion, _copyDestination);
if (_copyAfterBuild && !string.IsNullOrEmpty(_copyDestination))
{
CopyFiles(report.OutputPackageDirectory, _copyDestination);
}
EditorUtility.DisplayDialog("构建成功", $"AB包构建完成\n输出目录: {report.OutputPackageDirectory}", "确定");
}
else
{
EditorUtility.DisplayDialog("构建失败", $"错误信息: {report.ErrorInfo}", "确定");
}
}
catch (Exception e)
{
Debug.LogException(e);
}
}
private void BuildUpdateData(string version, string outPath)
{
ResourcePatchData updateData = new ResourcePatchData()
{
Version = Application.version,
BundleUrl = $"http://127.0.0.1:8081/res/{version}/",
Notice = "Test Notice",
};
File.WriteAllText(Path.Combine(outPath, "UpdateData.json"), Newtonsoft.Json.JsonConvert.SerializeObject(updateData));
}
private void CopyFiles(string source, string destination)
{
try
{
if (!Directory.Exists(destination))
{
Directory.CreateDirectory(destination);
}
foreach (string file in Directory.GetFiles(source))
{
File.Copy(file, Path.Combine(destination, Path.GetFileName(file)), true);
}
Debug.Log($"文件拷贝完成: {source} -> {destination}");
}
catch (Exception e)
{
Debug.LogError($"文件拷贝失败: {e.Message}");
}
}
private IEncryptionServices CreateEncryptionInstance()
{
if (string.IsNullOrEmpty(_selectedEncryption)) return null;
var type = Type.GetType(_selectedEncryption);
if (type != null)
{
return (IEncryptionServices)Activator.CreateInstance(type);
}
return null;
}
}