2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
8.5 KiB
C#

2 years ago
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<LevelNode> _levelData = new List<LevelNode>();
private readonly List<LevelNodeDoor> _doorList = new List<LevelNodeDoor>();
private readonly List<LevelNodePlayerBorn> _playerBornList = new List<LevelNodePlayerBorn>();
private readonly List<int> _interactList = new List<int>(); //通关后打开的交互物
private readonly List<Material> _wallMaterialList = new List<Material>();
private static readonly int WorldPos = Shader.PropertyToID("_WorldPos");
protected override void OnCreate()
{
base.OnCreate();
_gameObject.SetActive(true);
EventManager.Instance.AddEvent<PEntityAlive>(EEvent.EntityAlive, OnEntityAlive);
}
protected override void OnDestroy()
{
EventManager.Instance.RemoveEvent<PEntityAlive>(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<LevelNode>();
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<SpriteRenderer>();
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<LevelMarkAirWall>();
foreach (var item in walls)
{
if (!item.TryGetComponent<MeshRenderer>(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();
}
}
}