218 lines
9.2 KiB
C#
218 lines
9.2 KiB
C#
using UnityEngine;
|
||
using TMPro;
|
||
using RuntimeData;
|
||
using Logic;
|
||
|
||
namespace TH1Renderer
|
||
{
|
||
public class ProjectileRenderer
|
||
{
|
||
private MapData _mapData;
|
||
private Main _main;
|
||
|
||
private GameObject _ROprojectile;
|
||
private ProjectileData _projectileData;
|
||
|
||
//------- Update缓存数据 -------//
|
||
private UnitData _unitData;
|
||
private GridData _gridData;
|
||
private PlayerData _playerData;
|
||
|
||
// 移动相关变量
|
||
private bool _needMove = false;
|
||
private Vector3 moveStartPos;
|
||
private Vector3 moveEndPos;
|
||
private float moveTime = 0f;
|
||
private float moveFullTime = 1f;
|
||
|
||
public ProjectileRenderer(GameObject prefab,Transform father, ProjectileData projectileData, MapData mapData, Main main)
|
||
{
|
||
_mapData = mapData;
|
||
_main = main;
|
||
_projectileData = projectileData;
|
||
_ROprojectile = GameObject.Instantiate(prefab, projectileData.StartPos, Quaternion.identity, father);
|
||
//每个projectile从创生就要开始move
|
||
_needMove = true;
|
||
moveTime = 0f;
|
||
moveStartPos = projectileData.StartPos;
|
||
moveEndPos = projectileData.EndPos;
|
||
|
||
foreach (Transform child in _ROprojectile.transform)
|
||
child.gameObject.SetActive(false);
|
||
|
||
if (projectileData.ProjectileType == ProjectileType.Arrow)
|
||
{
|
||
_ROprojectile.transform.Find("Arrow").gameObject.SetActive(true);
|
||
moveFullTime = Table.Instance.AnimDataAssets.ProjectileMoveTime;
|
||
}
|
||
else if (projectileData.ProjectileType == ProjectileType.Bomb)
|
||
{
|
||
_ROprojectile.transform.Find("Bomb").gameObject.SetActive(true);
|
||
moveFullTime = Table.Instance.AnimDataAssets.ProjectileBombMoveTime;
|
||
}
|
||
else if (projectileData.ProjectileType == ProjectileType.CityExp)
|
||
{
|
||
_ROprojectile.transform.Find("CityExp").gameObject.SetActive(true);
|
||
moveFullTime = Table.Instance.AnimDataAssets.ProjectileCityExpMoveTime;
|
||
}
|
||
else if (projectileData.ProjectileType == ProjectileType.Coin)
|
||
{
|
||
_ROprojectile.transform.Find("Coin").gameObject.SetActive(true);
|
||
moveFullTime = Table.Instance.AnimDataAssets.ProjectileCoinMoveTime;
|
||
}
|
||
}
|
||
|
||
|
||
public GameObject GetROUnit() { return _ROprojectile; }
|
||
|
||
public void Die()
|
||
{
|
||
GameObject.Destroy(_ROprojectile.gameObject);
|
||
}
|
||
|
||
public void Update()
|
||
{
|
||
// 如果需要移动
|
||
if (_needMove)
|
||
{
|
||
float parabola_height = 0f;
|
||
float time_para = 1f;
|
||
if (_projectileData.ProjectileMoveType == ProjectileMoveType.Parabola)
|
||
parabola_height = 0.3f;
|
||
if (_projectileData.ProjectileMoveType == ProjectileMoveType.HighParabola)
|
||
parabola_height = 0.5f;
|
||
if (_projectileData.ProjectileMoveType == ProjectileMoveType.CityExpHighParabola)
|
||
parabola_height = 0.6f;
|
||
if (_projectileData.ProjectileMoveType == ProjectileMoveType.CoinParabola)
|
||
parabola_height = -0.1f;
|
||
|
||
|
||
Vector3 linearPos;
|
||
Vector3 finalPos;
|
||
float arcHeight;
|
||
float arcOffset;
|
||
float t;
|
||
//如果是coin 完全单独处理
|
||
if (_projectileData.ProjectileMoveType == ProjectileMoveType.CoinParabola)
|
||
{
|
||
var startPos = moveStartPos;
|
||
startPos.y -= 5f;
|
||
var middlePos = startPos;
|
||
|
||
middlePos.y -= 2f;
|
||
// 增加时间
|
||
moveTime += Time.deltaTime / moveFullTime;
|
||
float showTime = 0.3f;
|
||
//前showTime%的时间轻微移动
|
||
if (moveTime < showTime)
|
||
{
|
||
t = Mathf.Clamp01(moveTime/showTime);
|
||
|
||
// 计算水平线性插值位置
|
||
linearPos = Vector3.Lerp(startPos, middlePos, t);
|
||
|
||
// 添加抛物线效果 (在y轴方向)
|
||
// 使用sin函数创建一个弧形,在中间点达到最高
|
||
arcHeight = Vector3.Distance(startPos, middlePos) * parabola_height; // 弧高为距离的20%
|
||
arcOffset = Mathf.Sin(t * Mathf.PI) * arcHeight;
|
||
|
||
// 最终位置 = 线性插值位置 + 抛物线高度偏移
|
||
finalPos = new Vector3(
|
||
linearPos.x,
|
||
linearPos.y + arcOffset,
|
||
linearPos.z
|
||
);
|
||
|
||
// 设置投射物位置
|
||
_ROprojectile.transform.position = finalPos;
|
||
}
|
||
//后70%的时间才做抛物线
|
||
else
|
||
{
|
||
// 计算当前位置的插值因子 (0到1之间)
|
||
t = Mathf.Clamp01((moveTime - showTime) / (1f - showTime));
|
||
|
||
// 计算水平线性插值位置
|
||
linearPos = Vector3.Lerp(middlePos, moveEndPos, t);
|
||
|
||
// 添加抛物线效果 (在y轴方向)
|
||
// 使用sin函数创建一个弧形,在中间点达到最高
|
||
arcHeight = Vector3.Distance(middlePos, moveEndPos) * parabola_height; // 弧高为距离的20%
|
||
arcOffset = Mathf.Sin(t * Mathf.PI) * arcHeight;
|
||
|
||
// 最终位置 = 线性插值位置 + 抛物线高度偏移
|
||
finalPos = new Vector3(
|
||
linearPos.x,
|
||
linearPos.y + arcOffset,
|
||
linearPos.z
|
||
);
|
||
|
||
// 设置投射物位置
|
||
_ROprojectile.transform.position = finalPos;
|
||
}
|
||
|
||
|
||
// 如果移动完成
|
||
if (moveTime >= 1.0f)
|
||
{
|
||
_needMove = false;
|
||
// 延迟销毁投射物
|
||
GameObject.Destroy(_ROprojectile);
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
//处理其他的运动曲线
|
||
|
||
// 增加时间
|
||
moveTime += Time.deltaTime / moveFullTime;
|
||
|
||
// 计算当前位置的插值因子 (0到1之间)
|
||
t = Mathf.Clamp01(moveTime);
|
||
|
||
// 计算水平线性插值位置
|
||
linearPos = Vector3.Lerp(moveStartPos, moveEndPos, t);
|
||
|
||
// 添加抛物线效果 (在y轴方向)
|
||
// 使用sin函数创建一个弧形,在中间点达到最高
|
||
arcHeight = Vector3.Distance(moveStartPos, moveEndPos) * parabola_height; // 弧高为距离的20%
|
||
arcOffset = Mathf.Sin(t * Mathf.PI) * arcHeight;
|
||
|
||
// 最终位置 = 线性插值位置 + 抛物线高度偏移
|
||
finalPos = new Vector3(
|
||
linearPos.x,
|
||
linearPos.y + arcOffset,
|
||
linearPos.z
|
||
);
|
||
|
||
// 设置投射物位置
|
||
_ROprojectile.transform.position = finalPos;
|
||
|
||
// 根据移动方向更新投射物的旋转
|
||
if (_projectileData.ProjectileMoveType != ProjectileMoveType.CityExpHighParabola && t < 0.99f) // 避免在最后时刻计算方向
|
||
{
|
||
Vector3 direction = (t < 0.98f) ?
|
||
(_ROprojectile.transform.position - _ROprojectile.transform.position - _ROprojectile.transform.forward) :
|
||
(moveEndPos - _ROprojectile.transform.position).normalized;
|
||
|
||
if (direction != Vector3.zero)
|
||
{
|
||
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
|
||
_ROprojectile.transform.rotation = Quaternion.Euler(0, 0, angle - 90); // 假设精灵默认朝上
|
||
}
|
||
}
|
||
|
||
// 如果移动完成
|
||
if (moveTime >= 1.0f)
|
||
{
|
||
_needMove = false;
|
||
// 延迟销毁投射物
|
||
GameObject.Destroy(_ROprojectile);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
} |