TH1/Unity/Assets/Scripts/TH1_Renderer/ProjectileManager.cs
2026-06-20 14:07:40 +08:00

249 lines
9.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<uint, ProjectileData> ProjectileDataDict;
public Dictionary<uint, ProjectileRenderer> 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<uint, ProjectileData>();
ROProjectileMap = new Dictionary<uint, ProjectileRenderer>();
_projectilePrefab = TH1Resource.ResourceLoader.Load<GameObject>($"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<TextMeshPro>().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<TextMeshPro>().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)
{
}
}
}