find-object-bundle-builder/pipeline_Profile/build_profile_package/Assets/Editor/BuildBundlesHelper.cs

398 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections.Generic;
using System.IO;
using TEngine.Editor.Resource;
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;
using YooAsset.Editor;
public static class BuildBundlesHelper
{
private static BuildParameters GetParametersFromParams(BuildTarget buildTarget, string buildVersion)
{
BuildParameters buildParameters = new BuildParameters()
{
StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot(),
BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(),
BuildTarget = buildTarget,
BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline,
BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode,
PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage,
PackageVersion = buildVersion,
VerifyBuildingResult = true,
SharedPackRule = new ZeroRedundancySharedPackRule(),
EncryptionServices = new FileStreamEncryption(),
CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption,
OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle,
CopyBuildinFileOption = ECopyBuildinFileOption.None,
CopyBuildinFileTags = AssetBundleBuilderSettingData.Setting.CopyBuildinFileTags,
EnableLog = false,
};
if (AssetBundleBuilderSettingData.Setting.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
buildParameters.SBPParameters = new BuildParameters.SBPBuildParameters();
buildParameters.SBPParameters.WriteLinkXML = true;
}
return buildParameters;
}
[MenuItem("Tools/TestBuildBundles")]
public static void TestBuildBundles()
{
Debug.LogWarning("MakePrefabs Start ==================");
MakePrefabs();
Debug.LogWarning("MakePrefabs End ==================");
Debug.LogWarning("MakeAtlas Start ==================");
MakeAtlas();
AssetDatabase.Refresh();
Debug.LogWarning("MakeAtlas End ==================");
Debug.LogWarning("Create YooAsset Package Start ==========");
CreateYooAssetPackage();
AssetDatabase.Refresh();
Debug.LogWarning("Create YooAsset Package End ==========");
Debug.LogWarning("BuildBundles Start ==================");
AssetBundleCollectorSetting setting =
AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
if (setting == null)
{
Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
return;
}
var bundleBuilder = new AssetBundleBuilder();
BuildParameters buildParameters = GetParametersFromParams(BuildTarget.Android, "1.0.0");
string outputDir = $"{buildParameters.BuildOutputRoot}/{buildParameters.BuildTarget.ToString()}";
Debug.LogError($"bundle资源输出目录:{outputDir}");
if (Directory.Exists(outputDir))
Directory.Delete(outputDir, true);
for (int i = 0; i < setting.Packages.Count; i++)
{
var package = setting.Packages[i];
if (package.PackageName == "DefaultPackage")
continue;
buildParameters.PackageName = package.PackageName;
bundleBuilder.Run(buildParameters);
}
Debug.LogWarning("BuildBundles End ==================");
}
public static void BuildBundles()
{
Debug.LogWarning("MakePrefabs Start ==================");
MakePrefabs();
Debug.LogWarning("MakePrefabs End ==================");
Debug.LogWarning("MakeAtlas Start ==================");
MakeAtlas();
AssetDatabase.Refresh();
Debug.LogWarning("MakeAtlas End ==================");
Debug.LogWarning("Create YooAsset Package Start ==========");
CreateYooAssetPackage();
AssetDatabase.Refresh();
Debug.LogWarning("Create YooAsset Package End ==========");
Debug.LogWarning("BuildBundles Start ==================");
AssetBundleCollectorSetting setting =
AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
if (setting == null)
{
Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
return;
}
BuildParams bp = BuildParamsHelper.GetBuildParams();
bp.Description();
var bundleBuilder = new AssetBundleBuilder();
BuildParameters buildParameters = null;
if (bp.Platform == "Android")
buildParameters = GetParametersFromParams(BuildTarget.Android, bp.BuildVersion);
else if (bp.Platform == "iOS")
buildParameters = GetParametersFromParams(BuildTarget.iOS, bp.BuildVersion);
if (buildParameters == null)
{
Debug.LogError($"不支持的平台:{bp.Platform}");
return;
}
string outputDir = $"{buildParameters.BuildOutputRoot}/{buildParameters.BuildTarget.ToString()}";
Debug.LogError($"bundle资源输出目录:{outputDir}");
if (Directory.Exists(outputDir))
Directory.Delete(outputDir, true);
for (int i = 0; i < setting.Packages.Count; i++)
{
var package = setting.Packages[i];
if (package.PackageName == "DefaultPackage")
continue;
buildParameters.PackageName = package.PackageName;
bundleBuilder.Run(buildParameters);
}
Debug.LogWarning("BuildBundles End ==================> exe");
}
#region 创建边框预制体
[MenuItem("Tools/MakePrefabs")]
public static void MakePrefabsMenuItem()
{
MakePrefabs();
}
/// <summary>
/// 根据指定文件夹中的PNG图片生成预制体
/// </summary>
/// <param name="dir">包含PNG图片的文件夹路径</param>
public static void MakePrefabs(string dir = "Assets/AssetRaw/UIRaw/frame_image")
{
if (!AssetDatabase.IsValidFolder(dir))
{
Debug.LogError($"不存在的目录:{dir}");
return;
}
// 获取文件夹中所有PNG图片
string[] allPics = Directory.GetFiles(dir, "*.png", SearchOption.TopDirectoryOnly);
if (allPics.Length == 0)
{
Debug.LogError($"目录中没有找到PNG图片:{dir}");
return;
}
// 创建预制体保存目录
string prefabDir = dir.Replace("frame_image", "frame_prefabs");
if (!AssetDatabase.IsValidFolder(prefabDir))
{
Directory.CreateDirectory(prefabDir);
AssetDatabase.Refresh();
}
int successCount = 0;
foreach (var picPath in allPics)
{
if (picPath.EndsWith(".meta"))
continue;
// 转换为Unity资源路径
string assetPath = picPath.Replace("\\", "/");
// 加载Sprite资源
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);
if (sprite == null)
{
Debug.LogWarning($"无法加载Sprite: {assetPath}");
continue;
}
// 从文件名提取数字部分作为预制体名称
string fileName = Path.GetFileNameWithoutExtension(assetPath);
string prefabName = ExtractNumberFromFileName(fileName);
if (string.IsNullOrEmpty(prefabName))
{
Debug.LogWarning($"无法从文件名提取数字: {fileName}");
continue;
}
// 创建预制体
if (CreateFramePrefab(sprite, prefabName, prefabDir))
{
successCount++;
Debug.Log($"成功创建预制体: {prefabName}");
}
}
AssetDatabase.Refresh();
Debug.Log($"预制体创建完成,成功创建 {successCount} 个预制体");
}
/// <summary>
/// 从文件名中提取数字部分
/// </summary>
/// <param name="fileName">文件名,如 "frame_2000"</param>
/// <returns>提取的数字字符串,如 "2000"</returns>
private static string ExtractNumberFromFileName(string fileName)
{
// 查找最后一个下划线的位置
int lastUnderscoreIndex = fileName.LastIndexOf('_');
if (lastUnderscoreIndex >= 0 && lastUnderscoreIndex < fileName.Length - 1)
{
string numberPart = fileName.Substring(lastUnderscoreIndex + 1);
// 验证是否为纯数字
if (System.Text.RegularExpressions.Regex.IsMatch(numberPart, @"^\d+$"))
{
return numberPart;
}
}
// 如果没有找到下划线,尝试提取文件名中的所有数字
var match = System.Text.RegularExpressions.Regex.Match(fileName, @"\d+");
if (match.Success)
{
return match.Value;
}
return null;
}
/// <summary>
/// 创建包含Image组件的预制体
/// </summary>
/// <param name="sprite">要使用的Sprite</param>
/// <param name="prefabName">预制体名称</param>
/// <param name="prefabDir">预制体保存目录</param>
/// <returns>是否创建成功</returns>
private static bool CreateFramePrefab(Sprite sprite, string prefabName, string prefabDir)
{
try
{
// 创建空的GameObject
GameObject frameObject = new GameObject(prefabName);
// 添加RectTransform组件UI元素必需
RectTransform rectTransform = frameObject.AddComponent<RectTransform>();
// 添加Image组件
UnityEngine.UI.Image imageComponent = frameObject.AddComponent<UnityEngine.UI.Image>();
imageComponent.sprite = sprite;
imageComponent.preserveAspect = true;
// 设置RectTransform的大小为图片的实际像素大小
rectTransform.sizeDelta = new Vector2(sprite.rect.width, sprite.rect.height);
// 设置为中心对齐
rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
rectTransform.pivot = new Vector2(0.5f, 0.5f);
rectTransform.anchoredPosition = Vector2.zero;
// 确保Image组件不会改变原始图片尺寸
imageComponent.type = UnityEngine.UI.Image.Type.Simple;
imageComponent.preserveAspect = false; // 改为false严格按照sizeDelta设置的尺寸显示
// 保存为预制体
string prefabPath = $"{prefabDir}/{prefabName}.prefab";
GameObject prefab = PrefabUtility.SaveAsPrefabAsset(frameObject, prefabPath);
// 清理临时GameObject
Object.DestroyImmediate(frameObject);
return prefab != null;
}
catch (System.Exception e)
{
Debug.LogError($"创建预制体失败 {prefabName}: {e.Message}");
return false;
}
}
#endregion
#region 创建图集
private static void MakeAtlas()
{
string dir = $"Assets/AssetRaw/UIRaw";
if (!AssetDatabase.IsValidFolder(dir))
{
Debug.LogError($"不存在的目录:{dir}");
}
MakeAtlas(dir);
}
private static void MakeAtlas(string dirPath)
{
string[] allPics = Directory.GetFiles(dirPath, "*.png", SearchOption.AllDirectories);
if (allPics.Length == 0)
{
Debug.LogError($"不存在的图:{dirPath}");
return;
}
List<Sprite> sprites = new List<Sprite>();
foreach (var picPath in allPics)
{
if (picPath.EndsWith(".meta"))
continue;
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(picPath);
if (sprite != null)
{
sprites.Add(sprite);
}
}
Debug.LogError(sprites.Count);
AtlasUtils.CreateAtlas($"profile_atlas", sprites, dirPath);
}
#endregion
private static void CreateYooAssetPackage()
{
AssetBundleCollectorSetting setting =
AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
if (setting == null)
{
Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
return;
}
//重置配置
for (int i = 0; i < setting.Packages.Count; i++)
{
if (setting.Packages[i].PackageName == "DefaultPackage")
continue;
setting.Packages.RemoveAt(i);
i--;
}
Debug.Log($"packge count:{setting.Packages.Count}");
//创建关卡资源package
string dir = $"Assets/AssetRaw/UIRaw";
if (!AssetDatabase.IsValidFolder(dir))
{
Debug.LogError($"不存在的目录:{dir}");
}
var levelName = "ProfilesFeatureV2";
AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
package.PackageName = levelName;
package.PackageDesc = $"profile玩法资源包";
package.Groups = new List<AssetBundleCollectorGroup>();
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
group.GroupName = "default";
group.AssetTags = levelName;
group.ActiveRuleName = "EnableGroup";
group.Collectors = new List<AssetBundleCollector>();
AssetBundleCollector collector = new AssetBundleCollector();
collector.CollectPath = dir;
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
collector.CollectorType = ECollectorType.MainAssetCollector;
collector.AddressRuleName = nameof(AddressByFileName);
collector.PackRuleName = nameof(PackCollector);
collector.FilterRuleName = nameof(CollectAll);
collector.AssetTags = levelName;
group.Collectors.Add(collector);
package.Groups.Add(group);
setting.Packages.Add(package);
AssetDatabase.SaveAssetIfDirty(setting);
}
}