This commit is contained in:
2026-08-28 19:42:54 +08:00
parent ccb8673313
commit 4b1f8acadf
14 changed files with 1797 additions and 6 deletions
@@ -7,6 +7,19 @@ using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using static UnityEngine.AddressableAssets.Addressables;
/// <summary>
/// 战神预制体用途:战神有两个预制体(展示/游戏内使用),名字相同,靠 Addressables 子标签区分。
/// - Display:Default 子标签(大厅/商城预览模型)
/// - GamePlay:ZSYX 子标签(座位上替代普通炮台的使用模型)
/// </summary>
public enum ZhanShenUsage
{
/// <summary>展示用:大厅/商城预览模型(Default 子标签加载)</summary>
Display = 0,
/// <summary>游戏内用:座位上替代普通炮台的模型(ZSYX 子标签加载)</summary>
GamePlay = 1
}
[Serializable]
public class TurretResourcesData
{
@@ -20,8 +33,9 @@ public class TurretResourcesData
public List<int> bulletID; // 子弹 ID 列表
// ---- Addressables 标签 ----
const string turret_AALabel = "PTCBZS"; // 炮台统一标签
const string defaultSubLabel = "Default"; // 默认子标签
const string turret_AALabel = "PTCBZS"; // 炮台统一标签(主标签:炮台/翅膀/战神共用)
const string defaultSubLabel = "Default"; // 展示子标签(展示用预制体:普通炮台/翅膀/战神展示)
const string zhanShenGameSubLabel = "ZSYX"; // 战神游戏内子标签(战神的使用预制体,与展示同名靠标签区分)
// ---- 路径→ID 映射(用于 Addressables 加载时反查) ----
private static Dictionary<string, int> turretPrefabPathDic; // prefabPath → turretNumber
@@ -29,7 +43,8 @@ public class TurretResourcesData
// ---- ID→数据/资源 映射 ----
public static Dictionary<int, TurretResourcesData> turretDataDic; // id → data
private static Dictionary<int, GameObject> turretPrefabDic; // id → prefab
private static Dictionary<int, GameObject> turretPrefabDic; // id → 展示用预制体(Default 子标签)
private static Dictionary<int, GameObject> turretGamePrefabDic; // id → 战神游戏内使用预制体(ZSYX 子标签)
private static Dictionary<int, Sprite> turretSpriteDic; // id → sprite
// ---- 保留的 AA Handle(不释放,避免 Build 下资源被卸载)----
@@ -96,13 +111,16 @@ public class TurretResourcesData
// ==================== 资源加载 ====================
/// <summary>
/// 加载炮台相关 Addressables 资源(PT + Default 标签交集)。
/// 加载炮台相关 Addressables 资源(两组标签交集):
/// - PT + Default:普通炮台/翅膀/战神展示预制体 → turretPrefabDic;
/// - PT + ZSYX:战神游戏内使用预制体 → turretGamePrefabDic(与展示同名,靠标签区分)。
/// 注意:Handle 必须保留,不能 Release,否则 Build 下资源会被立即卸载,
/// 字典中存的就是已销毁对象的引用(Editor 下因 AssetDatabase 模式不会暴露此问题)。
/// </summary>
public static async Task LoadTurretAssetsData()
{
turretPrefabDic = new Dictionary<int, GameObject>();
turretGamePrefabDic = new Dictionary<int, GameObject>();
turretSpriteDic = new Dictionary<int, Sprite>();
// 清理上一轮残留的 Handle
@@ -112,7 +130,10 @@ public class TurretResourcesData
}
_loadedHandles.Clear();
// 展示用标签组:PT + Default(普通炮台/翅膀/战神展示预制体)
var labels = new List<string> { turret_AALabel, defaultSubLabel };
// 战神游戏内标签组:PT + ZSYX(战神的使用预制体,名字与展示相同)
var zsGameLabels = new List<string> { turret_AALabel, zhanShenGameSubLabel };
Debug.Log("[TurretResourcesData] 开始预下载炮台资源依赖 (PT + Default)...");
var depHandle = Addressables.DownloadDependenciesAsync(labels, MergeMode.Intersection);
@@ -120,7 +141,13 @@ public class TurretResourcesData
Addressables.Release(depHandle); // 预下载 Handle 可以立即释放,只影响下载缓存
Debug.Log("[TurretResourcesData] 炮台依赖资源预下载完成!");
// ---- 加载炮台 Prefab ----
Debug.Log("[TurretResourcesData] 开始预下载战神游戏内资源依赖 (PT + ZSYX)...");
var zsDepHandle = Addressables.DownloadDependenciesAsync(zsGameLabels, MergeMode.Intersection);
await zsDepHandle.Task;
Addressables.Release(zsDepHandle);
Debug.Log("[TurretResourcesData] 战神游戏内依赖资源预下载完成!");
// ---- 加载炮台 Prefab(展示用)----
var prefabHandle = Addressables.LoadAssetsAsync<GameObject>(labels, prefab =>
{
if (turretPrefabPathDic.TryGetValue(prefab.name, out int id))
@@ -135,6 +162,23 @@ public class TurretResourcesData
_loadedHandles.Add(prefabHandle);
Debug.Log($"[TurretResourcesData] 炮台 Prefab 加载完成,共 {turretPrefabDic.Count} 个");
// ---- 加载战神游戏内 Prefab(ZSYX 子标签;与展示同名,靠标签区分)----
var zsPrefabHandle = Addressables.LoadAssetsAsync<GameObject>(zsGameLabels, prefab =>
{
if (turretPrefabPathDic.TryGetValue(prefab.name, out int id)
&& turretDataDic.TryGetValue(id, out var data)
&& data.turretType == 2) // 只收战神(turretType==2)的游戏内使用预制体
{
turretGamePrefabDic[id] = prefab;
Debug.Log($"[TurretResourcesData] 加载战神游戏内 Prefab: {prefab.name} (ID={id})");
}
}, MergeMode.Intersection);
await zsPrefabHandle.Task;
// 不释放!保留 Handle 以保持资源存活
_loadedHandles.Add(zsPrefabHandle);
Debug.Log($"[TurretResourcesData] 战神游戏内 Prefab 加载完成,共 {turretGamePrefabDic.Count} 个");
// ---- 加载炮台 Sprite ----
var spriteHandle = Addressables.LoadAssetsAsync<Sprite>(labels, data =>
{
@@ -170,9 +214,10 @@ public class TurretResourcesData
_loadedHandles.Clear();
turretPrefabDic?.Clear();
turretGamePrefabDic?.Clear();
turretSpriteDic?.Clear();
Debug.Log($"[TurretResourcesData] 卸载完成,剩余 Prefab: {turretPrefabDic?.Count ?? 0}, Sprite: {turretSpriteDic?.Count ?? 0}");
Debug.Log($"[TurretResourcesData] 卸载完成,剩余 Prefab: {turretPrefabDic?.Count ?? 0}, 战神游戏内: {turretGamePrefabDic?.Count ?? 0}, Sprite: {turretSpriteDic?.Count ?? 0}");
return Task.CompletedTask;
}
@@ -190,6 +235,18 @@ public class TurretResourcesData
return turretPrefabDic != null && turretPrefabDic.TryGetValue(turretNumber, out var prefab) ? prefab : null;
}
/// <summary>
/// 根据战神编号获取战神预制体(两种情况二选一)。
/// - Display:展示用(大厅/商城预览,与 GetTurretPrefab 返回同一个展示模型);
/// - GamePlay:游戏内用(座位上替代普通炮台的使用模型)。
/// 未加载、非战神或未配置使用预制体时返回 null。
/// </summary>
public static GameObject GetZhanShenPrefab(int turretNumber, ZhanShenUsage usage = ZhanShenUsage.Display)
{
var dic = usage == ZhanShenUsage.GamePlay ? turretGamePrefabDic : turretPrefabDic;
return dic != null && dic.TryGetValue(turretNumber, out var prefab) ? prefab : null;
}
/// <summary>根据 ID 获取炮台 Sprite。</summary>
public static Sprite GetTurretSprite(int turretNumber)
{