根据提供的code differences信息,由于没有具体的代码变更内容,我将生成一个通用的commit message模板:
``` docs(readme): 更新文档说明 - 添加项目使用指南 - 完善API接口说明 - 修正错误的配置示例 ``` 注意:由于您提供的code differences部分为空,以上是一个示例模板。当您有具体的代码变更时,请提供详细的变更内容以便生成更准确的commit message。
This commit is contained in:
1 parent
8d58c2223c
commit
11f1af357d
191 files changed
+2315
-1539
No files matched your search
@@ -0,0 +1,261 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 战斗场景的出战生成:开战前按阵型数据在对应格位生成英雄。
|
||||
/// 优先使用阵型编排场景保存的数据;没有编排数据时按名单使用默认阵型(近战前排 / 远程后排)。
|
||||
/// </summary>
|
||||
public class BattleFormationSpawner : MonoBehaviour
|
||||
{
|
||||
[Header("出战英雄名单(没有编排数据时的默认来源)")]
|
||||
public HeroRoster roster;
|
||||
|
||||
[Header("生成到哪个父节点(留空则放在场景根)")]
|
||||
public Transform heroParent;
|
||||
|
||||
[Header("玩家阵营 ID")]
|
||||
public int playerTeamId = 0;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
spawnedHeroCount = 0; // 重置计数器
|
||||
SpawnHeroes();
|
||||
}
|
||||
|
||||
private void SpawnHeroes()
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
for (int i = 0; i < FormationData.HeroPrefabs.Length; i++)
|
||||
{
|
||||
int cell = i < FormationData.CellIndices.Length ? FormationData.CellIndices[i] : -1;
|
||||
if (FormationData.HeroPrefabs[i] == null || !DeployGrid.IsValidIndex(cell))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Spawn(FormationData.HeroPrefabs[i], cell);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
int meleeTotal = 0, rangedTotal = 0;
|
||||
foreach (HeroEntry entry in roster.heroes)
|
||||
{
|
||||
if (entry == null) continue;
|
||||
if (entry.isMelee) meleeTotal++; else rangedTotal++;
|
||||
}
|
||||
|
||||
var used = new HashSet<int>();
|
||||
int meleeIndex = 0, rangedIndex = 0;
|
||||
|
||||
foreach (HeroEntry entry in roster.heroes)
|
||||
{
|
||||
if (entry == null || entry.prefab == null) continue;
|
||||
|
||||
int cell = entry.isMelee
|
||||
? DeployGrid.DefaultCell(true, meleeIndex++, meleeTotal)
|
||||
: DeployGrid.DefaultCell(false, rangedIndex++, rangedTotal);
|
||||
|
||||
if (used.Contains(cell))
|
||||
{
|
||||
cell = NextFreeCell(cell, used);
|
||||
}
|
||||
if (cell < 0) continue;
|
||||
|
||||
used.Add(cell);
|
||||
Spawn(entry.prefab, cell);
|
||||
}
|
||||
}
|
||||
|
||||
private static int NextFreeCell(int from, HashSet<int> used)
|
||||
{
|
||||
for (int i = 0; i < DeployGrid.CellCount; i++)
|
||||
{
|
||||
int candidate = (from + i) % DeployGrid.CellCount;
|
||||
if (!used.Contains(candidate)) return candidate;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int spawnedHeroCount = 0; // 记录已生成英雄数量(改为实例变量)
|
||||
|
||||
private void Spawn(GameObject prefab, int cell)
|
||||
{
|
||||
CharacterData characterData = FindCharacterDataForPrefab(prefab);
|
||||
Vector3 spawnPos = DeployGrid.CellPosition(cell);
|
||||
GameObject unit = Instantiate(prefab, spawnPos, Quaternion.identity);
|
||||
unit.name = "英雄_" + prefab.name;
|
||||
|
||||
if (heroParent != null)
|
||||
{
|
||||
unit.transform.SetParent(heroParent, true);
|
||||
}
|
||||
|
||||
UnitTeam team = unit.GetComponent<UnitTeam>();
|
||||
if (team != null)
|
||||
{
|
||||
team.teamId = playerTeamId;
|
||||
}
|
||||
|
||||
UnitBase unitBase = unit.GetComponent<UnitBase>();
|
||||
if (unitBase != null)
|
||||
{
|
||||
unitBase.returnToAnchorWhenIdle = true;
|
||||
unitBase.anchorArrivalDistance = 0.35f;
|
||||
}
|
||||
|
||||
if (characterData != null && unitBase != null)
|
||||
{
|
||||
PlayerCharacterData playerData = PlayerDataManager.Instance != null
|
||||
? PlayerDataManager.Instance.GetCharacterData(characterData.characterId)
|
||||
: null;
|
||||
int level = playerData != null ? playerData.level : 1;
|
||||
unitBase.InitializeFromPlayerData(
|
||||
characterData.GetMaxHealth(level),
|
||||
characterData.GetAttackPower(level),
|
||||
characterData.GetMoveSpeed(level));
|
||||
}
|
||||
|
||||
// 设置友方英雄可复活
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar != null && playerTeamId == 0)
|
||||
{
|
||||
healthBar.canRevive = true;
|
||||
}
|
||||
|
||||
// 绑定到英雄卡片UI
|
||||
BindHeroToCard(unit, characterData, spawnPos);
|
||||
}
|
||||
|
||||
private void BindHeroToCard(GameObject heroUnit, CharacterData characterData, Vector3 spawnPos)
|
||||
{
|
||||
if (spawnedHeroCount >= 5)
|
||||
{
|
||||
Debug.LogWarning($"已达到最大英雄数量5,跳过绑定 {heroUnit.name}");
|
||||
return; // 最多5个英雄
|
||||
}
|
||||
|
||||
// 查找 TowerDefenseCanvas
|
||||
GameObject canvasObj = GameObject.Find("TowerDefenseCanvas");
|
||||
if (canvasObj == null)
|
||||
{
|
||||
Debug.LogError("BindHeroToCard: 未找到 TowerDefenseCanvas");
|
||||
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)
|
||||
{
|
||||
Debug.LogError($"BindHeroToCard: 未找到 {cardName}");
|
||||
return;
|
||||
}
|
||||
|
||||
HeroCardUI heroCardUI = cardObj.GetComponent<HeroCardUI>();
|
||||
if (heroCardUI == null)
|
||||
{
|
||||
Debug.LogError($"BindHeroToCard: {cardName} 缺少 HeroCardUI 组件");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取英雄单位组件
|
||||
UnitBase unitBase = heroUnit.GetComponent<UnitBase>();
|
||||
if (unitBase == null)
|
||||
{
|
||||
Debug.LogError($"BindHeroToCard: {heroUnit.name} 缺少 UnitBase 组件");
|
||||
return;
|
||||
}
|
||||
|
||||
// 加载对应的头像
|
||||
UnityEngine.Sprite icon = characterData != null ? characterData.cardIcon : null;
|
||||
|
||||
// 绑定英雄到卡片
|
||||
heroCardUI.SetHero(unitBase, icon, spawnPos);
|
||||
|
||||
spawnedHeroCount++;
|
||||
|
||||
Debug.Log($"✅ {cardName} 已绑定英雄: {heroUnit.name}(第 {spawnedHeroCount} 个)");
|
||||
}
|
||||
|
||||
private CharacterData FindCharacterDataForPrefab(GameObject prefab)
|
||||
{
|
||||
if (prefab == null) return null;
|
||||
return Resources.LoadAll<CharacterData>("Data")
|
||||
.FirstOrDefault(data => data != null && data.unitPrefab == prefab);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user