feat(player): 添加玩家阵型保存功能

新增savedFormation字段用于存储玩家的阵型配置,
包括角色ID列表和对应的格子索引位置信息。
```
This commit is contained in:
huadexuan committed 2026-09-29 23:21:44 +08:00
1 parent e127da5416
commit 1abd0de32f
16 files changed
+432 -2930

No files matched your search

+93 -13
View File
@@ -25,7 +25,19 @@ public class BattleFormationSpawner : MonoBehaviour
private void SpawnHeroes()
{
// 1. 玩家编排过的阵型
// 1. 优先从 PlayerData.json 读取保存的阵型
if (PlayerDataManager.Instance != null)
{
SavedFormationData formationData = PlayerDataManager.Instance.LoadFormation();
if (formationData != null && formationData.characterIds != null && formationData.characterIds.Length > 0)
{
Debug.Log($"从 PlayerData.json 加载阵型,共 {formationData.characterIds.Length} 个英雄");
SpawnFromSavedFormation(formationData);
return;
}
}
// 2. 回退到 FormationData(场景间临时传递的数据)
if (FormationData.HasCustomFormation
&& FormationData.HeroPrefabs != null
&& FormationData.HeroPrefabs.Length > 0)
@@ -42,10 +54,54 @@ public class BattleFormationSpawner : MonoBehaviour
return;
}
// 2. 没有编排数据:默认阵型
// 3. 没有任何编排数据:使用默认阵型
SpawnDefaultFormation();
}
/// <summary>
/// 从保存的阵型数据生成英雄
/// </summary>
private void SpawnFromSavedFormation(SavedFormationData formationData)
{
for (int i = 0; i < formationData.characterIds.Length; i++)
{
string characterId = formationData.characterIds[i];
int cell = i < formationData.cellIndices.Length ? formationData.cellIndices[i] : -1;
if (string.IsNullOrEmpty(characterId) || !DeployGrid.IsValidIndex(cell))
{
continue;
}
// 根据 characterId 找到对应的 Prefab
GameObject prefab = FindPrefabByCharacterId(characterId);
if (prefab != null)
{
Spawn(prefab, cell);
}
else
{
Debug.LogWarning($"未找到 characterId={characterId} 对应的 Prefab");
}
}
}
/// <summary>
/// 根据 characterId 查找对应的 Prefab
/// </summary>
private GameObject FindPrefabByCharacterId(string characterId)
{
var allData = Resources.LoadAll<CharacterData>("Data");
foreach (var data in allData)
{
if (data.characterId == characterId)
{
return data.unitPrefab;
}
}
return null;
}
private void SpawnDefaultFormation()
{
if (roster == null || roster.heroes == null) return;
@@ -89,7 +145,7 @@ public class BattleFormationSpawner : MonoBehaviour
return -1;
}
private static int spawnedHeroCount = 0; // 记录已生成英雄数量
private int spawnedHeroCount = 0; // 记录已生成英雄数量(改为实例变量)
private void Spawn(GameObject prefab, int cell)
{
@@ -141,25 +197,49 @@ public class BattleFormationSpawner : MonoBehaviour
private void BindHeroToCard(GameObject heroUnit, CharacterData characterData, Vector3 spawnPos)
{
if (spawnedHeroCount >= 5) return; // 最多5个英雄
if (spawnedHeroCount >= 5)
{
Debug.LogWarning($"已达到最大英雄数量5,跳过绑定 {heroUnit.name}");
return; // 最多5个英雄
}
// 查找对应的卡片
Canvas canvas = FindObjectOfType<Canvas>();
if (canvas == null) return;
// 查找 TowerDefenseCanvas
GameObject canvasObj = GameObject.Find("TowerDefenseCanvas");
if (canvasObj == null)
{
Debug.LogError("BindHeroToCard: 未找到 TowerDefenseCanvas");
return;
}
Transform heroPanel = canvas.transform.Find("BottomUI/HeroCardsPanel");
if (heroPanel == null) return;
Transform heroPanel = canvasObj.transform.Find("BottomUI/HeroCardsPanel");
if (heroPanel == null)
{
Debug.LogError("BindHeroToCard: 未找到 BottomUI/HeroCardsPanel");
return;
}
string cardName = $"HeroCard{spawnedHeroCount + 1}";
Transform cardObj = heroPanel.Find(cardName);
if (cardObj == null) return;
if (cardObj == null)
{
Debug.LogError($"BindHeroToCard: 未找到 {cardName}");
return;
}
HeroCardUI heroCardUI = cardObj.GetComponent<HeroCardUI>();
if (heroCardUI == null) return;
if (heroCardUI == null)
{
Debug.LogError($"BindHeroToCard: {cardName} 缺少 HeroCardUI 组件");
return;
}
// 获取英雄单位组件
UnitBase unitBase = heroUnit.GetComponent<UnitBase>();
if (unitBase == null) return;
if (unitBase == null)
{
Debug.LogError($"BindHeroToCard: {heroUnit.name} 缺少 UnitBase 组件");
return;
}
// 加载对应的头像
UnityEngine.Sprite icon = characterData != null ? characterData.cardIcon : null;
@@ -169,7 +249,7 @@ public class BattleFormationSpawner : MonoBehaviour
spawnedHeroCount++;
Debug.Log($"英雄 {heroUnit.name} 已绑定到 {cardName}");
Debug.Log($"✅ {cardName} 已绑定英雄: {heroUnit.name}(第 {spawnedHeroCount} 个)");
}
private CharacterData FindCharacterDataForPrefab(GameObject prefab)