在游戏开发中,抛物线轨迹 广泛用于 投掷物、弹道轨迹、跳跃路径 等场景。例如,投掷手雷、弓箭射击、篮球投篮 等都需要显示轨迹。
Unity 提供了 LineRenderer
组件,可以用来动态绘制抛物线轨迹。本篇博客将介绍 抛物线的原理、如何用 LineRenderer
实现抛物线,以及优化技巧。
1. 抛物线的运动原理
物体在重力作用下的运动轨迹符合抛物线方程,其位置随时间变化,满足以下公式:
x = v 0 ⋅ t ⋅ cos ( θ ) x = v_0 \cdot t \cdot \cos(\theta) x=v0⋅t⋅cos(θ)
y = v 0 ⋅ t ⋅ sin ( θ ) − 1 2 g t 2 y = v_0 \cdot t \cdot \sin(\theta) - \frac{1}{2} g t^2 y=v0⋅t⋅sin(θ)−21gt2
其中:
- ( x , y x, y x,y ):物体在世界坐标中的位置
- ( v 0 v_0 v0 ):初始速度
- ( θ \theta θ ):发射角度(以弧度计算)
- ( g g g ):重力加速度(Unity 中通常设为
Physics.gravity.y
) - ( t t t ):时间(随
Time.deltaTime
递增)
核心思想:
- 每隔一小段时间计算物体的 新位置,并用
LineRenderer
连接这些点,就可以形成一条 抛物线轨迹。
2. 使用 LineRenderer
绘制抛物线
① 创建 LineRenderer
在 Unity 中:
- 创建一个空物体
- 添加
LineRenderer
组件 - 使用代码动态绘制抛物线
② 代码实现抛物线
我们将编写 ParabolaRenderer
脚本,实现抛物线轨迹绘制。
using UnityEngine;
public class ParabolaRenderer : MonoBehaviour
{
public LineRenderer lineRenderer; // 线渲染组件
public Transform startPoint; // 起始位置
public float launchAngle = 45f; // 抛射角度
public float launchSpeed = 10f; // 初速度
public int resolution = 30; // 轨迹点数量
public float timeStep = 0.1f; // 采样间隔
private void Start()
{
DrawParabola();
}
void DrawParabola()
{
lineRenderer.positionCount = resolution; // 设置 LineRenderer 点数
Vector3[] points = new Vector3[resolution];
float gravity = Mathf.Abs(Physics.gravity.y); // 获取重力加速度
float angleRad = launchAngle * Mathf.Deg2Rad; // 角度转弧度
Vector3 startPosition = startPoint.position; // 获取起始位置
Vector3 velocity = new Vector3(Mathf.Cos(angleRad), Mathf.Sin(angleRad), 0) * launchSpeed; // 计算初速度
for (int i = 0; i < resolution; i++)
{
float t = i * timeStep; // 计算时间
float x = velocity.x * t; // x 轴运动
float y = velocity.y * t - 0.5f * gravity * t * t; // y 轴运动
points[i] = startPosition + new Vector3(x, y, 0); // 计算轨迹点
}
lineRenderer.SetPositions(points); // 应用轨迹点
}
}
③ 代码解析
-
计算初始速度方向
Vector3 velocity = new Vector3(Mathf.Cos(angleRad), Mathf.Sin(angleRad), 0) * launchSpeed;
- 通过
角度转换为弧度
,再用sin
和cos
计算速度的X
、Y
方向分量。
- 通过
-
计算轨迹点
float x = velocity.x * t; float y = velocity.y * t - 0.5f * gravity * t * t;
x
方向匀速运动y
方向受到重力影响,符合抛物线公式
-
更新 LineRenderer
lineRenderer.SetPositions(points);
- 计算得到
positionCount
个轨迹点,传递给LineRenderer
绘制曲线。
- 计算得到
3. 进一步优化抛物线
① 使抛物线朝向鼠标方向
在 Z
轴方向旋转抛物线,使其指向目标点(如鼠标点击处)。
Vector3 direction = (targetPosition - startPoint.position).normalized;
Vector3 velocity = direction * launchSpeed;
② 增加碰撞检测
在 DrawParabola()
内部添加 Physics.Raycast()
,让抛物线在撞到障碍物时停止。
RaycastHit hit;
if (Physics.Raycast(startPosition, velocity, out hit, velocity.magnitude * t))
{
points[i] = hit.point; // 停止计算
lineRenderer.positionCount = i + 1; // 限制轨迹长度
break;
}
应用场景:手雷投掷、弓箭轨迹
③ 让抛物线在 3D 世界中显示
当前 LineRenderer
轨迹 仅限于 2D(X-Y 平面)。
如果要在 3D 世界 使用:
Vector3 velocity = startPoint.forward * launchSpeed; // 让投掷方向跟随角色视角
这样可以让抛物线在 任何方向投掷,适用于 FPS 投掷武器。
4. 总结
功能 | 实现方式 |
---|---|
绘制抛物线 | 使用 LineRenderer 连接轨迹点 |
计算轨迹 | 物理公式:x = v*t*cos(θ) , y = v*t*sin(θ) - 0.5*g*t² |
调整方向 | 计算 velocity 方向,使抛物线朝向目标 |
碰撞检测 | Physics.Raycast() 让抛物线提前停止 |
3D 适配 | 让 velocity 方向跟随摄像机视角 |
5. 适用场景
✅ 手雷投掷(如《CS:GO》、《PUBG》)
✅ 弓箭轨迹(如《塞尔达传说》)
✅ 篮球投篮(如《NBA 2K》)
✅ 跳跃路径(如《超级马里奥》)
6. 结论
使用 LineRenderer
绘制抛物线是 简单且高效 的方法。掌握 轨迹计算、方向调整、碰撞检测 后,就可以轻松在 3D 场景 中绘制精准的投掷轨迹!