using Fort23.Core; using UnityEngine; namespace Core.Utility { public class Parabola3DPath: CObject { public Vector3 startPos; public Vector3 targetPos; public float gravity = 9.8f; public Vector3 initialVelocity; // 物体的初始速度 public float totalFlightTime; public Parabola3DPath() { } public Parabola3DPath(Vector3 startPos,Vector3 targetPos) { SetPos(startPos,targetPos); } public void SetPos(Vector3 startPos, Vector3 targetPos) { this.startPos = startPos; this.targetPos = targetPos; CalculateInitialVelocity(); } // 计算发射物体的初始速度和飞行时间 void CalculateInitialVelocity() { Vector3 startPosition = startPos; Vector3 targetPosition = targetPos; // 计算目标的水平距离和垂直高度差 float deltaX = targetPosition.x - startPosition.x; float deltaY = targetPosition.y - startPosition.y; float deltaZ = targetPosition.z - startPosition.z; // deltaY += 2; // 计算水平距离(包括 X 和 Z 轴) float horizontalDistance = Mathf.Sqrt(deltaX * deltaX + deltaZ * deltaZ); // 计算飞行所需的时间 totalFlightTime = CalculateFlightTime(horizontalDistance, deltaY); // 计算发射的初速度 initialVelocity = CalculateInitialVelocityVector(deltaX, deltaZ, deltaY, totalFlightTime); } // 计算飞行时间 float CalculateFlightTime(float horizontalDistance, float deltaY) { // 使用物理公式来计算飞行时间:竖直分量的运动方程 // time = sqrt(2 * (deltaY + horizontalDistance * tan(45))) / gravity float time = Mathf.Sqrt((2 * (deltaY + horizontalDistance * Mathf.Tan(Mathf.Deg2Rad * 45f))) / gravity); return time; } // 计算初速度向量 Vector3 CalculateInitialVelocityVector(float deltaX, float deltaZ, float deltaY, float timeToTarget) { // 计算水平速度分量 float v_x = deltaX / timeToTarget; // X轴速度 float v_z = deltaZ / timeToTarget; // Z轴速度 // 垂直速度 float v_y = (deltaY + 0.5f * gravity * timeToTarget * timeToTarget) / timeToTarget; // 初速度向量 Vector3 velocity = new Vector3(v_x, v_y, v_z); return velocity; } public Vector3 GetPositionAtTime(float t) { t = Mathf.Clamp(t, 0, 1); // 计算每个轴的位移 float deltaX = initialVelocity.x * t; float deltaY = initialVelocity.y * t - 0.5f * gravity * t * t; float deltaZ = initialVelocity.z * t; // 返回当前位置 return new Vector3(startPos.x + deltaX, startPos.y + deltaY, startPos.z + deltaZ); } public override void ActiveObj() { } public override void DormancyObj() { } } }