Files
daluandou/Assets/Script/BattleFormationSpawner.cs
T
huadexuan e127da5416 根据提供的code differences信息,由于没有具体的代码变更内容,我将生成一个通用的commit message模板:
```
docs(readme): 更新文档说明

- 添加项目使用指南
- 完善API接口描述
- 修正错误的配置示例
```

注意:由于您提供的code differences部分为空,无法确定具体的变更类型和范围。实际使用时请根据真实变更内容替换相应的type、scope、subject和body信息。
2026-09-29 17:52:10 +08:00

182 lines
5.8 KiB
C#

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. 玩家编排过的阵型
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;
}
// 2. 没有编排数据:默认阵型
SpawnDefaultFormation();
}
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 static 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) return; // 最多5个英雄
// 查找对应的卡片
Canvas canvas = FindObjectOfType<Canvas>();
if (canvas == null) return;
Transform heroPanel = canvas.transform.Find("BottomUI/HeroCardsPanel");
if (heroPanel == null) return;
string cardName = $"HeroCard{spawnedHeroCount + 1}";
Transform cardObj = heroPanel.Find(cardName);
if (cardObj == null) return;
HeroCardUI heroCardUI = cardObj.GetComponent<HeroCardUI>();
if (heroCardUI == null) return;
// 获取英雄单位组件
UnitBase unitBase = heroUnit.GetComponent<UnitBase>();
if (unitBase == null) return;
// 加载对应的头像
UnityEngine.Sprite icon = characterData != null ? characterData.cardIcon : null;
// 绑定英雄到卡片
heroCardUI.SetHero(unitBase, icon, spawnPos);
spawnedHeroCount++;
Debug.Log($"英雄 {heroUnit.name} 已绑定到 {cardName}");
}
private CharacterData FindCharacterDataForPrefab(GameObject prefab)
{
if (prefab == null) return null;
return Resources.LoadAll<CharacterData>("Data")
.FirstOrDefault(data => data != null && data.unitPrefab == prefab);
}
}