Files
5.24BuYu/Assets/Editor/AAFixDependencyMigration.cs
T
2026-10-09 16:45:46 +08:00

179 lines
8.7 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.Text;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
using UnityEngine;
/// <summary>
/// AA 依赖链修复迁移工具(一次性)。
///
/// 【背景】Addressables 加载 bundle 时会递归加载其依赖 bundle,而构建报告显示存在
/// 跨玩法依赖链,导致"未登录就加载鱼包 / 进 A 玩法拉 B 玩法鱼包":
/// defaultlocalgroup → fish_xjmh → fish_hhwk (启动链:默认音频一碰 D LG 全链拖入)
/// fish_flzy → fish_hhwk (进 FLZY 房拉 HHWK 鱼包)
/// gameuires → fish_xjmh (进任何房间拉 XJMH 鱼包)
///
/// 【修复内容】(对应 2026-10-08 16:41 构建报告分析出的确切依赖边)
/// 1. PW_Enemy_4000.prefab(XJMH Boss,误在 D LG)→ Fish_XJMH 组 断 D LG→fish_xjmh
/// 2. XJMHCreateFish.asset(XJMH 配置,误在 D LG)→ Fish_XJMH 组
/// 3. 新建 SharedRes 组:Game177_baigujing.png(HHWK 图鉴贴图被 XJMH 小丑扑克引用)、
/// fish_4003 Variant.png(HHWK 图鉴贴图被 FLZY 闪电引用)→ SharedRes
/// 断 fish_xjmh→fish_hhwk、fish_flzy→fish_hhwk(两边都只依赖小共享包)
/// 4. GameMainPanelXJMH 引用的 7 个 XJMH 资源(Boss出场特效/帮助Item/技能sprite)
/// → GameUIRes 组 断 gameuires→fish_xjmh
/// (若鱼包资产也引用它们,产生 fish_xjmh→gameuires 边——进房必载面板,无害)
///
/// 【使用】Unity 菜单 Tools → AA依赖修复 → 执行修复并重建Addressables,
/// 完成后用 AABundleMonitor 悬浮窗验证:启动仅 4 个包、进房只加当前玩法鱼包。
/// </summary>
public static class AAFixDependencyMigration
{
[MenuItem("Tools/AA依赖修复/执行修复并重建Addressables")]
public static void Run()
{
if (!EditorUtility.DisplayDialog("AA依赖修复",
"将执行以下迁移(断掉跨玩法 bundle 依赖链):\n\n" +
"1. PW_Enemy_4000 / XJMHCreateFish → Fish_XJMH 组\n" +
"2. 新建 SharedRes 组,移入 2 张被跨玩法引用的贴图\n" +
"3. GameMainPanelXJMH 引用的 7 个资源 → GameUIRes 组\n\n" +
"迁移完成后可选择立即重建 Addressables。\n继续?",
"执行", "取消"))
return;
var settings = AddressableAssetSettingsDefaultObject.Settings;
if (settings == null)
{
Debug.LogError("[AA依赖修复] 找不到 AddressableAssetSettings");
return;
}
var log = new StringBuilder();
// ---------- ① D LG 里误放的 XJMH 资产 → Fish_XJMH(断 D LG→fish_xjmh 启动链) ----------
var fishXjmh = settings.FindGroup("Fish_XJMH");
if (fishXjmh == null) { Debug.LogError("[AA依赖修复] 找不到 Fish_XJMH 组"); return; }
MoveWithLabels(settings, fishXjmh,
"Assets/MyGame/aa/Game/XJMH/Boss/XingJiXunHang/PW_Enemy_4000.prefab",
new[] { "FishPrefab", "XJMH" }, log);
MoveWithLabels(settings, fishXjmh,
"Assets/MyGame/aa/UI/Game/XJMH/XJMHCreateFish.asset",
new[] { "XJMH" }, log);
// ---------- ② 新建 SharedRes 组,移入被跨玩法引用的贴图(断 xjmh/flzy→hhwk) ----------
var shared = settings.FindGroup("SharedRes");
if (shared == null)
{
shared = CreateGroupLike(settings, "SharedRes", "Fish_XJMH");
log.AppendLine("[组] 已创建 SharedRes(打包配置复制自 Fish_XJMH)");
}
// 保留原 TuJian/HHWK 标签:HHWK 玩法的图鉴 Sprite 交集加载(TuJian+HHWK)仍能命中,
// 只是从 SharedRes 包里取;XJMH/FLZY 对它们的引用改为依赖小共享包
MoveKeepLabels(settings, shared, "Assets/Art/HHWK/res/texture/dynamic/Game177_baigujing.png", log);
MoveKeepLabels(settings, shared, "Assets/Art/HHWK/TuJianTexture/fish_4003 Variant.png", log);
// ---------- ③ GameMainPanelXJMH 引用的资源 → GameUIRes(断 gameuires→fish_xjmh) ----------
var gameUi = settings.FindGroup("GameUIRes");
if (gameUi == null) { Debug.LogError("[AA依赖修复] 找不到 GameUIRes 组"); return; }
string[] guiTargets =
{
"Assets/Art/XJMH/pw/pw_prefab/game/effect/PW_Effect_Boss_Appear.prefab",
"Assets/Art/XJMH/pw/pw_prefab/item/PW_HelpItem1.prefab",
"Assets/Art/XJMH/pw/pw_prefab/item/PW_HelpItem2.prefab",
"Assets/Art/XJMH/pw/pw_prefab/item/PW_SetLockItem.prefab",
"Assets/Art/XJMH/pw/pw_sprite/common/zd_jn_sd.png",
"Assets/Art/XJMH/pw/pw_sprite/common/zd_jn_ss.png",
"Assets/Art/XJMH/pw/pw_sprite/common/zd_jn_zd.png",
};
foreach (var t in guiTargets)
MoveKeepLabels(settings, gameUi, t, log);
AssetDatabase.SaveAssets();
Debug.Log("[AA依赖修复] 迁移完成:\n" + log);
// ---------- ④ 重建 ----------
if (EditorUtility.DisplayDialog("AA依赖修复",
"迁移完成:\n" + log + "\n现在重建 Addressables?(约几分钟)",
"立即重建", "稍后手动重建"))
{
Debug.Log("[AA依赖修复] 开始重建 Addressables...");
AddressableAssetSettings.BuildPlayerContent(out var result);
if (result == null || !string.IsNullOrEmpty(result.Error))
{
Debug.LogError("[AA依赖修复] 构建失败: " + (result != null ? result.Error : "无返回结果"));
EditorUtility.DisplayDialog("AA依赖修复", "构建失败: " + (result != null ? result.Error : "无返回结果"), "确定");
}
else
{
Debug.Log("[AA依赖修复] 构建完成");
EditorUtility.DisplayDialog("AA依赖修复",
"构建完成!\n\n验证步骤:\n" +
"1. Play 启动到登录页 → 悬浮窗应只有 4 个包(builtinshaders/LoginUIRes/DefaultLocalGroup/Turret)\n" +
"2. 进任一玩法房间 → 只新增该玩法的鱼包 + gameuires", "确定");
}
}
}
/// <summary>移动资产到目标组并覆盖标签</summary>
private static void MoveWithLabels(AddressableAssetSettings settings, AddressableAssetGroup target,
string path, string[] labels, StringBuilder log)
{
string guid = AssetDatabase.AssetPathToGUID(path);
if (string.IsNullOrEmpty(guid))
{
log.AppendLine("[跳过] 找不到资产: " + path);
return;
}
var entry = settings.CreateOrMoveEntry(guid, target);
if (entry == null)
{
log.AppendLine("[跳过] 移动失败: " + path);
return;
}
entry.labels.Clear();
foreach (var l in labels)
entry.labels.Add(l);
log.AppendLine($"[移动] {path}\n → {target.name}(标签: {string.Join(",", labels)})");
}
/// <summary>移动资产到目标组,保留原有标签</summary>
private static void MoveKeepLabels(AddressableAssetSettings settings, AddressableAssetGroup target,
string path, StringBuilder log)
{
string guid = AssetDatabase.AssetPathToGUID(path);
if (string.IsNullOrEmpty(guid))
{
log.AppendLine("[跳过] 找不到资产: " + path);
return;
}
var entry = settings.CreateOrMoveEntry(guid, target);
if (entry == null)
{
log.AppendLine("[跳过] 移动失败: " + path);
return;
}
log.AppendLine($"[移动] {path}\n → {target.name}(保留标签: {string.Join(",", entry.labels)})");
}
/// <summary>按源组的打包配置(BundledAssetGroupSchema/ContentUpdateGroupSchema)创建新组。
/// AddSchema(schema) 内部会复制 schema 并正确挂到新组上,无需手动 CopySerialized。</summary>
private static AddressableAssetGroup CreateGroupLike(AddressableAssetSettings settings,
string newName, string srcGroupName)
{
var src = settings.FindGroup(srcGroupName);
var group = settings.CreateGroup(newName, false, false, false, null);
var srcBundled = src.GetSchema<BundledAssetGroupSchema>();
if (srcBundled != null)
group.AddSchema(srcBundled, false);
var srcContent = src.GetSchema<ContentUpdateGroupSchema>();
if (srcContent != null)
group.AddSchema(srcContent, false);
return group;
}
}