99 lines
2.5 KiB
C#
99 lines
2.5 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
[RequireComponent(typeof(Rigidbody))]
|
|
public class FireBallProjectile : MonoBehaviour
|
|
{
|
|
[Header("Damage & Effect")]
|
|
public float damage = 20f;
|
|
public GameObject explosionFx;
|
|
|
|
[Header("Flight Settings")]
|
|
public float flightTime = 1.2f; // 飞行总时间
|
|
private Rigidbody rb;
|
|
|
|
private bool hasHit = false; // 防止重复伤害
|
|
|
|
void Awake()
|
|
{
|
|
rb = GetComponent<Rigidbody>();
|
|
rb.useGravity = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发射火球到目标位置,保证弧线落到 targetPos
|
|
/// </summary>
|
|
public void LaunchToTarget(Vector3 startPos, Vector3 targetPos, float flightTime)
|
|
{
|
|
transform.position = startPos;
|
|
|
|
Vector3 velocity = CalculateVelocity(startPos, targetPos, flightTime);
|
|
rb.velocity = velocity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算抛物线初速度,保证 t 秒后落到 target
|
|
/// </summary>
|
|
private Vector3 CalculateVelocity(Vector3 start, Vector3 target, float time)
|
|
{
|
|
Vector3 displacement = target - start;
|
|
|
|
// 水平位移
|
|
Vector3 displacementXZ = new Vector3(displacement.x, 0, displacement.z);
|
|
|
|
// 水平速度
|
|
Vector3 velocityXZ = displacementXZ / time;
|
|
|
|
// 垂直速度
|
|
float velocityY = displacement.y / time - 0.5f * Physics.gravity.y * time;
|
|
|
|
Vector3 result = velocityXZ + Vector3.up * velocityY;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置伤害
|
|
/// </summary>
|
|
public void SetDamage(float curDamage)
|
|
{
|
|
damage = curDamage;
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
if (hasHit) return;
|
|
|
|
if (other.CompareTag("Player"))
|
|
{
|
|
other.GetComponent<EnemyIDamagable>()?.ApplyDamage(damage, null, transform);
|
|
hasHit = true;
|
|
Explode();
|
|
}
|
|
}
|
|
|
|
private void OnCollisionEnter(Collision collision)
|
|
{
|
|
if (hasHit) return;
|
|
|
|
// 撞到玩家
|
|
if (collision.gameObject.CompareTag("Player"))
|
|
{
|
|
collision.gameObject.GetComponent<EnemyIDamagable>()?.ApplyDamage(damage, null, transform);
|
|
hasHit = true;
|
|
}
|
|
|
|
// 撞到地面或障碍物都爆炸
|
|
Explode();
|
|
}
|
|
|
|
private void Explode()
|
|
{
|
|
if (explosionFx != null)
|
|
{
|
|
Instantiate(explosionFx, transform.position, Quaternion.identity);
|
|
}
|
|
|
|
Destroy(gameObject);
|
|
}
|
|
}
|