using System; using System.Collections; using System.Collections.Generic; using KTGMGemClient; using UnityEngine; using TowerDefense.UI.HUD; namespace TowerDefense.Level { /// /// PVE 无尽模式一个关卡波次管理器 /// public class EndlessWaveManager : MonoBehaviour { /// /// 当前关卡等级的所有波数据 /// public List> LevelData { get; set; } /// /// 波次时间间隔 /// public float WaveInterval { get; set; } /// /// 怪物移速缩放 /// public float SpeedScale { get; set; } = 1.0f; /// /// 当前波索引 /// public int CurrentWaveIndex { get; protected set; } /// /// 当前波数据 /// protected List waveData; /// /// 实际上就是5条兵线 /// [Tooltip("Specify list in order")] public List waves = new List(); /// /// 当前WaveManager是否开始Wave. /// protected bool isWaveStarted = false; /// /// Called when all waves are finished /// public event Action AllWaveCompleted; /// /// 当前关卡的总波数 /// public int TotalWaves { get; protected set; } /// /// 当前波的赛道总数 /// public int TotalWaveLines { get; set; } /// /// 当前波已经完成的赛道数量 /// public int CompletedWaveLine { get; protected set; } /// /// 本波次敌人总数量 /// public int TotalEnemies { get; protected set; } /// /// 所有兵线已经生成的敌人总数量 /// /// public int SpawnedTotalEnemies { get; protected set; } /// /// 本波次剩余敌人数量 /// public int RemainEnemies { get; protected set; } /// /// 当前正在进行的关卡等级 /// public int Level { get; protected set; } /// /// 法阵 /// public List TunelList; private string tunelMaterialPath = "UI/Endless/Tunel/tunel_"; private string faZhenPath = "UI/Endless/Tunel/EndlessFaZhen"; private void Start() { HideTunel(); } /// /// 隐藏法阵,即怪出生的圈圈 /// public void HideTunel() { for (int i = 0; i < TunelList.Count; ++i) { TunelList[i].gameObject.SetActive(false); } } /// /// 显示法阵 /// public void ShowTunel() { for (int i = 0; i < TunelList.Count; ++i) { TunelList[i].gameObject.SetActive(true); } } /// /// Starts the waves /// /// 关卡等级 /// public virtual void StartWaves(int level) { Debug.Log($"--------------------- 开始第 {level} 关 ---------------------"); Level = level; LevelData = EndlessPortData.GetLevelWaveData(level); TotalWaves = LevelData.Count; CurrentWaveIndex = 0; EndlessBossHPManager.instance.InitHP(); EndlessLevelManager.instance.DecrementEnemies -= DecrementEnemies; EndlessLevelManager.instance.DecrementEnemies += DecrementEnemies; if (LevelData.Count == 0) throw new Exception($"当前关卡:{level}, 没有关卡数据"); UpdateWave(); } /// /// 敌人数量减少 /// /// public void DecrementEnemies(int count) { RemainEnemies -= count; // 改变血条的进度 EndlessBossHPManager.instance.SetCurrentProgress(RemainEnemies * 1f / TotalEnemies); } /// /// 获取当前Wave的开始位置 /// /// /// public Vector3 GetWaveEndPos(int waveline) { return waves[waveline].StartingNode.GetNextNode().transform.position; } private void RefreshBoss() { if (CurrentWaveIndex > 0 || TotalWaves == 1) EndlessBossHPManager.instance.SwitchHP(CurrentWaveIndex == TotalWaves - 1); EndlessBossHPManager.instance.SetBossInfo($"{waveData[0].Config.boss_name} Lv.{Level}"); EndlessBossHPManager.instance.UpdateWave(TotalWaves - CurrentWaveIndex); EndlessBossHPManager.instance.SetBossImage(waveData[0].Config.resource); EndlessBossHPManager.instance.ShowHP(); } /// /// 更新波 /// private void UpdateWave() { if (EndlessGameUI.instance.state == EndlessGameUI.State.GameOver) return; waveData = LevelData[CurrentWaveIndex]; // 直接取第一条就行了 WaveInterval = waveData[0].Config.cooldown / 1000f; TotalWaveLines = waveData.Count; CompletedWaveLine = 0; SpawnedTotalEnemies = 0; HideTunel(); // 刷新法阵的显示 for (int i = 0; i < waveData.Count; ++i) { int tunel = waveData[i].Config.tunel; TunelList[tunel - 1].material = Resources.Load($"{tunelMaterialPath}{tunel}"); GameObject obj = Resources.Load($"{faZhenPath}{tunel}"); GameObject faZhen = Instantiate(obj); faZhen.transform.SetParent(TunelList[tunel - 1].gameObject.transform); faZhen.transform.localPosition = new Vector3(0, 1, 0); faZhen.transform.localScale = new Vector3(2, 2, 2); TunelList[tunel - 1].gameObject.SetActive(true); ParticleSystem ps = faZhen.transform.GetChild(0).GetComponent(); ps.Play(); Destroy(ps.gameObject, ps.main.duration * 3); } RefreshBoss(); TotalEnemies = EndlessPortData.GetWaveEnemiesCount(Level, CurrentWaveIndex); RemainEnemies = TotalEnemies; foreach (EndlessPortConfig data in waveData) { // 兵线被摧毁了,就不再出兵了,实际上只要不是Wait状态 都应该不能出兵 if (waves[data.Config.tunel - 1].LineState == EndlessWaveLineState.Destroyed) { --TotalWaveLines; continue; } int tunelIndex = data.Config.tunel - 1; waves[tunelIndex].WaveCompleted -= OneWaveCompleted; waves[tunelIndex].WaveCompleted += OneWaveCompleted; waves[tunelIndex].SpawnNewAgent -= SpawnNewAgent; waves[tunelIndex].SpawnNewAgent += SpawnNewAgent; waves[data.Config.tunel - 1].StartWave(data); } if (TotalWaveLines != 0) isWaveStarted = true; } /// /// 有新的敌人生成 /// private void SpawnNewAgent() { ++SpawnedTotalEnemies; if (GameConfig.IsNewbie && EndlessUIStart.instance.beginSkillStep && SpawnedTotalEnemies >= 8) { EndlessUIStart.instance.beginSkillStep = false; EndlessLevelManager.instance.StopSecondWave(); } } /// /// 暂停所有兵线出兵 /// public void PauseAllWave() { foreach (EndlessPortConfig data in waveData) { if (waves[data.Config.tunel - 1].LineState == EndlessWaveLineState.Spawning) waves[data.Config.tunel - 1].PauseWave(); } } /// /// 恢复所有兵线出兵 /// public void RestartAllWave() { foreach (EndlessPortConfig data in waveData) { if (waves[data.Config.tunel - 1].LineState == EndlessWaveLineState.Spawning) waves[data.Config.tunel - 1].RestartWave(); } } /// /// 一波结束了 /// private void OneWaveCompleted() { ++CompletedWaveLine; } public void Update() { if (!isWaveStarted) return; if (CompletedWaveLine >= TotalWaveLines) { // 判断所有敌人是否全部清除 WaveLineAgentInsMgr[] waveLineAgentIns = AgentInsManager.instance.GetWaveLineList(); // 判断是否敌人数量为0 for (int i = 0; i < waveLineAgentIns.Length; ++i) { if (waveLineAgentIns[i].getAgentInsNum() != 0) return; } // 更新波索引 ++CurrentWaveIndex; EndlessBuffManager.instance.UpdateBuffList(); if (CurrentWaveIndex >= TotalWaves) // 当前关卡的所有波次全部完成 SafelyCallSpawningCompleted(); else { isWaveStarted = false; // 当前波的所有赛道都已经完成出怪 StartCoroutine(DelayToUpdateWave()); } } } /// /// 延迟去更新新的一波 /// /// private IEnumerator DelayToUpdateWave() { yield return new WaitForSeconds(WaveInterval); UpdateWave(); } /// /// Calls allWaveCompleted event /// protected virtual void SafelyCallSpawningCompleted() { isWaveStarted = false; EndlessBossHPManager.instance.UpdateWave(TotalWaves - CurrentWaveIndex); if (AllWaveCompleted != null) AllWaveCompleted(); } } }