using System.Collections.Generic; using Game; using UnityEngine; using Articy.Touhou.Features; using Ludiq; public class LevelPoolItem : ObjectPoolItemBase { public string CfgId; public LevelFeature Cfg; public LevelNodeMonsterWave CurWave; //当前波次配置 private GameObject _gameObject; private Vector3 _playerBorn = GameConst.NoneDir; //玩家出生点 private int _waveMax = 0; //最大波数 private int _waveNow = 0; //当前波数 private int _monsterCount = 0; //场景内怪物数 private readonly List _levelData = new List(); private readonly List _doorList = new List(); private readonly List _playerBornList = new List(); private readonly List _interactList = new List(); //通关后打开的交互物 private readonly List _wallMaterialList = new List(); private static readonly int WorldPos = Shader.PropertyToID("_WorldPos"); protected override void OnCreate() { base.OnCreate(); _gameObject.SetActive(true); EventManager.Instance.AddEvent(EEvent.EntityAlive, OnEntityAlive); } protected override void OnDestroy() { EventManager.Instance.RemoveEvent(EEvent.EntityAlive, OnEntityAlive); base.OnDestroy(); DestroyLevel(); _gameObject.SetActive(false); } protected override void OnCreateBind() { var master = Util.GetMaster(); BindData(master.view.PosView, ((pre, now) => { foreach (var item in _wallMaterialList) { item.SetVector(WorldPos, now); } })); } public void Init() { //关卡配置解析 var prefabPath = Cfg.Prefab; //关卡go创建 _gameObject = LevelPoolManager.Instance.CreateLevelGo(prefabPath); //位置分布 var nodes = _gameObject.GetComponentsInChildren(); foreach (var item in nodes) { item.SetPos(item.transform.position); item.OnInit(); switch (item) { case LevelNodePlayerBorn born: _playerBornList.Add(born); continue; case LevelNodeMonster itemLevelNodeMonster: var monsterId = Cfg.MonsterList[itemLevelNodeMonster.monsterIndex].TechnicalName; itemLevelNodeMonster.SetCfgId(monsterId); continue; case LevelNodeMonsterWave itemLevelNodeMonsterWave: if (itemLevelNodeMonsterWave.transform.childCount == 0) continue; itemLevelNodeMonsterWave.SetWaveIndex(_waveMax); _waveMax++; break; case LevelNodeDoor door: door.SetCfgId(Cfg.Door.TechnicalName); door.SetTargetLevel(Cfg); _doorList.Add(door); break; case LevelNodeNpc npc: npc.SetCfgId(npc.npcId); npc.SetTargetId(npc.dialogId); break; } _levelData.Add(item); } //开启阴影 var sprites = _gameObject.GetComponentsInChildren(); foreach (var item in sprites) { item.receiveShadows = false; item.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; } //墙壁 var levelRect = new Vector2(Cfg.LevelSizeX, Cfg.LevelSizeY) * 12.81f; var walls = _gameObject.GetComponentsInChildren(); foreach (var item in walls) { if (!item.TryGetComponent(out var meshRenderer)) continue; var material = meshRenderer.material; var mainTexture = (Texture2D)material.mainTexture; var textureSize = mainTexture.Size() / 64f; _wallMaterialList.Add(material); if (item.transform.localScale.z > 1f) { //竖向墙 material.mainTextureScale = new Vector2(levelRect.x / textureSize.x, 20 / textureSize.y) * 2; } else { //横向墙 material.mainTextureScale = new Vector2(levelRect.y / textureSize.x, 20 / textureSize.y) * 2; } } } public void SetPlayerBorn(string preLevelId) { //出生点选取规则:优先选择关卡连接关系对应,否则从playerBorn中随机 _playerBorn = GameConst.NoneDir; if (!string.IsNullOrEmpty(preLevelId)) { foreach (var item in _doorList) { if (item.IsFromPreLevel(preLevelId)) { _playerBorn = item.GetPos(); return; } } } if (_playerBornList.Count > 0) { _playerBorn = GameRandom.Pick(_playerBornList).GetPos(); return; } Util.Print("关卡配置错误,没有出生点"); } public void CreateLevel() { Util.GetMaster().SetFixedPos(_playerBorn); foreach (var item in _levelData) { if (item is LevelNodeMonsterWave) { continue; //进入关卡时不刷怪 } Util.CreateEntity(item.GetCfgId(), (entity) => { entity.SetPos(item.GetPos()); if (item is LevelNodeDoor) { entity.interact.TargetId = item.GetTargetId(); entity.interact.IsActive.Value = _waveMax == 0; _interactList.Add(entity.ID()); } if (item is LevelNodeNpc) { entity.interact.TargetId = item.GetTargetId(); } }); } NextWave(); } private void NextWave() { _monsterCount = 0; var isOk = false; if (_waveNow > _waveMax) { Util.Print("通关"); //通关 foreach (var interact in _interactList) { var entity = Util.GetEntity(interact); if (entity != null) { entity.interact.IsActive.Value = true; } } isOk = true; //TODO } else { foreach (var item in _levelData) { if (item is LevelNodeMonsterWave) { var itemLevelNodeMonsterWave = item as LevelNodeMonsterWave; if (itemLevelNodeMonsterWave.GetWaveIndex() == _waveNow) { foreach (var monster in itemLevelNodeMonsterWave.GetMonsters()) { Util.CreateEntity(monster.GetCfgId(), (entity) => { entity.SetPos(monster.GetPos()); }); } isOk = true; CurWave = itemLevelNodeMonsterWave; break; } } } if (isOk) { Util.Print("创建怪物实体 波数:", _waveNow); } } _waveNow++; if (!isOk) { NextWave(); } } private void DestroyLevel() { //TODO 销毁实体、特效等 var entities = Util.GetGroup(GameMatcher.ID); foreach (var item in entities) { if (item.IsMaster() || item.IsMasterSoul()) { continue; } item.OnDie(); item.iD.Data.IsDestroy = true; } //销毁残影和尸体 Util.DestroyCastShadowAll(); _waveNow = 0; CurWave = null; _interactList.Clear(); } private void OnEntityAlive(PEntityAlive param) { var entity = param.Entity; if (entity == Util.GetMasterID()) { return; } _monsterCount += (param.IsAlive ? 1 : -1); if (_monsterCount == 0) { NextWave(); } } }