using System.Collections.Generic; using Logic.Audio; using UnityEngine; using RuntimeData; using TH1_Core.Managers; using TH1_Logic.Core; using TMPro; namespace TH1Renderer { public enum ProjectileType { None, Melee, Arrow, Bomb, MagicFireBall,CityExp,Coin, Faith, RemiliaAttack, PatchouliAttack, MokouAttack, ReisenAttack, KaguyaAttack, KanakoAttack, SuwakoAttack, SanaeAttack, SanaeOmikuji, SatoriAttack, RinIndianAttack, ReimuAttack, ReimuExterminationOrb, SumirekoOccultOrb, ReimuDreamOrb1Red, ReimuDreamOrb2Blue, ReimuDreamOrb3Green, ReimuDreamOrb4Purple, ReimuDreamOrb5Gold, } public enum ProjectileMoveType { Straight, Parabola,HighParabola,CityExpHighParabola, CoinParabola,Spin, Curved,Bounce,SpecialAnimation,SpinHighParabola,OrbBezier} public class ProjectileData { public MapData MapData; public uint Id; public ProjectileType ProjectileType; public ProjectileMoveType ProjectileMoveType; public Vector3 StartPos; public Vector3 EndPos; public int Dis; public ProjectileData(MapData mapData,uint id,ProjectileType projectileType,ProjectileMoveType moveType,Vector3 startPos,Vector3 endPos,int dis = 1) { MapData = mapData; Id = id; ProjectileType = projectileType; ProjectileMoveType = moveType; StartPos = startPos; EndPos = endPos; Dis = dis; } } public class ProjectileManager { public uint IdCalculater; public Dictionary ProjectileDataDict; public Dictionary ROProjectileMap; //存储的projectileRenderMap对象(在主界面挂在谁下面)和projectilePrefab对象(用来实例化) private GameObject _projectilePrefab; private Transform _projectileRenderMap; private Transform _coinTransform; private Transform _faithTransform; public void Init(Transform trans) { IdCalculater = 0; _projectileRenderMap = trans; ProjectileDataDict = new Dictionary(); ROProjectileMap = new Dictionary(); _projectilePrefab = TH1Resource.ResourceLoader.Load($"Prefab/projectilePrefab"); } public void Update() { foreach(var t in ROProjectileMap) t.Value.Update(); } //返回coin要改飞往的地方 private Vector3 GetCoinPos() { if (_coinTransform == null) { _coinTransform = UIManager.Instance.UITopManager.GetCoinTransform(); } return _coinTransform.position; } private Vector3 GetFaithPos() { if (_faithTransform == null) { _faithTransform = UIManager.Instance.UITopManager.GetFaithTransform(); } return _faithTransform.position; } public void CreateProjectileFaith(Vector3 startPos, int score) { CreateProjectile(startPos,GetFaithPos(),ProjectileType.Faith,score); } //TODO legacy方案,后续迭代,用下面那个(飞行方式不要传入,因为走info //创建一个飞行道具,要传入起始位置和结束位置,然后传入飞行道具类型,飞行方式 /*public void CreateProjectile(Vector3 startPos, Vector3 endPos, ProjectileType projectileType, ProjectileMoveType moveType, int para = -1,int dis = 1) { var mapData = Main.MapData; //如果不在视野,不处理 mapData.GridMap.GetGridDataByVector3Pos(startPos, out var g1); mapData.GridMap.GetGridDataByVector3Pos(endPos,out var g2); if (g1 == null || g2 == null) return; if (!mapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(g1.Id) && mapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(g2.Id)) return; //先创建新的projectileData数据 var t = new ProjectileData(mapData, IdCalculater++, projectileType, moveType, startPos, endPos,dis); ProjectileDataDict[t.Id] = t; //再创建对应projectileRender对象,以及绑定的prefab ROProjectileMap[t.Id] = new ProjectileRenderer(_projectilePrefab, _projectileRenderMap, t); if (projectileType == ProjectileType.Faith) ROProjectileMap[t.Id].GetROProjectile().transform.Find("Faith/Text").GetComponent().text = "+" + para; }*/ public void CreateProjectile(Vector3 startPos, Vector3 endPos, ProjectileType projectileType,int para = 0) { if (!Table.Instance.ProjectileTypeDataAssets.GetProjectileTypeInfo(projectileType, out var info)) return; //CreateProjectile(startPos,endPos,projectileType,info.MoveType); var mapData = Main.MapData; //如果不在视野,不处理 /*mapData.GridMap.GetGridDataByVector3Pos(startPos, out var g1); mapData.GridMap.GetGridDataByVector3Pos(endPos,out var g2); if (g1 == null || g2 == null) return; if (!mapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(g1.Id) && mapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(g2.Id)) return;*/ //para通常用于表示dis int times = para; if (projectileType != ProjectileType.CityExp) times = 1; //先创建新的projectileData数据 var t = new ProjectileData(mapData, IdCalculater++, projectileType, info.MoveType, startPos, endPos,dis:times); ProjectileDataDict[t.Id] = t; //再创建对应projectileRender对象,以及绑定的prefab ROProjectileMap[t.Id] = new ProjectileRenderer(_projectilePrefab, _projectileRenderMap, t); if (projectileType == ProjectileType.Faith) ROProjectileMap[t.Id].GetROProjectile().transform.Find("Faith/Text").GetComponent().text = "+" + para; //处理音频 if (info.HasSFX) { if (info.HasSFXDelay) { Timer.Instance.TimerRegister(this, () => { AudioManager.Instance.PlayAudio(info.SFXName); },info.AnimTime,"ProjectileManager_SFXDelay"); } else { AudioManager.Instance.PlayAudio(info.SFXName); } } } //TODO 把这里multi函数和上面的projectile函数,全部换成便捷方式(下方的Coin和Faith public void CreateProjectileMulti(Vector3 startPos, Vector3 endPos, ProjectileType projectileType, ProjectileMoveType moveType,int count, float interval = 0.1f) { var mapData = Main.MapData; if (count == 0) return; //如果不在视野,不处理 if(mapData.GridMap.GetGridDataByVector3Pos(startPos, out var g1) && mapData.GridMap.GetGridDataByVector3Pos(endPos,out var g2)) if (!mapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(g1.Id) && mapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(g2.Id)) return; count--; //先创建新的projectileData数据 var t = new ProjectileData(mapData, IdCalculater++, projectileType, moveType, startPos, endPos); ProjectileDataDict[t.Id] = t; //再创建对应projectileRender对象,以及绑定的prefab ROProjectileMap[t.Id] = new ProjectileRenderer(_projectilePrefab, _projectileRenderMap, t); float tt = 0f; while (count > 0) { count--; tt += interval; Timer.Instance.TimerRegister(this, () => { var ttt = new ProjectileData(mapData, IdCalculater++, projectileType, moveType, startPos, endPos); ProjectileDataDict[t.Id] = t; //再创建对应projectileRender对象,以及绑定的prefab ROProjectileMap[ttt.Id] = new ProjectileRenderer(_projectilePrefab, _projectileRenderMap, t); } ,tt,"ProjectileManager_CreateMulti"); //先创建新的projectileData数据 } } //发起coin获得动画的便捷函数 public void CreateCoinProjectile(Vector3 startPos,int count) { CreateProjectileMulti(startPos, GetCoinPos(), ProjectileType.Coin, ProjectileMoveType.CoinParabola, count: count, interval: 0.05f); } //发起faith获得动画的便捷函数 public void CreateFaithProjectile(Vector3 startPos,int num) { } } }