Unity 里如何画一条曲线
在计算机图形学中,贝塞尔曲线(Bezier Curve) 是一种常见的曲线表示方法。 无论是在 2D 环境(如 HTMLCanvas)还是在 3D 游戏引擎 Unity 中,贝塞尔曲线都被广泛应用,例如路径规划、UI 动画、摄像机轨迹等。
本篇文章将带你一步步在 Unity3D 中绘制一条 三次贝塞尔曲线,并和 2D HTMLCanvas 的实现方式做一个对比。
一、什么是贝塞尔曲线?
- 二次贝塞尔曲线:由 3 个点决定(起点 P0、控制点 P1、终点 P2)。
- 三次贝塞尔曲线:由 4 个点决定(起点 P0、控制点 P1、控制点 P2、终点 P3)。
三次贝塞尔曲线公式为:
$$ B(t) = (1-t)^3 P0 + 3(1-t)^2 t P1 + 3(1-t) t^2 P2 + t^3 P3, \quad 0 \leq t \leq 1 $$
这条公式就是我们在 Unity 中生成曲线点的数学基础。
二、Unity3D 中绘制贝塞尔曲线的步骤
1. 创建控制点
在 Unity 场景中:
-
新建一个
Empty Object
,命名为BezierManager
。 -
在其下创建 4 个子物体,分别代表 P0, P1, P2, P3。
- P0 = 起点
- P1 = 控制点 1
- P2 = 控制点 2
- P3 = 终点
这些点的位置可以随意调整,方便观察曲线变化。
2. 编写贝塞尔函数
新建一个 BezierCurve.cs
脚本,挂载到 BezierManager
上。
using UnityEngine;
public class BezierCurve : MonoBehaviour
{
public Transform p0, p1, p2, p3; // 控制点
[Range(10, 100)]
public int segments = 50; // 曲线分段数
private void OnDrawGizmos()
{
if (p0 == null || p1 == null || p2 == null || p3 == null) return;
Vector3 prevPoint = p0.position;
for (int i = 1; i <= segments; i++)
{
float t = i / (float)segments;
Vector3 point = CalculateCubicBezierPoint(t, p0.position, p1.position, p2.position, p3.position);
Gizmos.color = Color.red;
Gizmos.DrawLine(prevPoint, point);
prevPoint = point;
}
}
// 三次贝塞尔公式
private Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
float u = 1 - t;
return u * u * u * p0
+ 3 * u * u * t * p1
+ 3 * u * t * t * p2
+ t * t * t * p3;
}
}
运行效果:在 Scene 视图中,你会看到一条由红色线段组成的平滑曲线,连接起点和终点,并受到两个控制点的影响。
3. 进一步拓展
- 如果需要在运行时显示,可以用 LineRenderer 替代
Gizmos.DrawLine
。 - 如果要在曲线上移动物体,可以在
Update()
里随时间更新参数t
并获取曲线点坐标。
三、对比:Unity3D 与 HTMLCanvas 的异同点
相同点
- 数学原理相同:都依赖贝塞尔曲线公式,通过控制点插值生成曲线。
- 控制点数量相同:二次需要 3 个点,三次需要 4 个点。
- 参数 t 的使用相同:t 从 0 到 1,表示从起点到终点的插值过程。
不同点
方面 | HTMLCanvas (2D) | Unity3D (3D) |
---|---|---|
绘制方式 | context.bezierCurveTo() 内置 API | 需手动计算点位并用线段连接 |
维度 | 2D 平面 (x, y) | 3D 空间 (x, y, z) |
坐标系 | 左上角为 (0,0),向右下为正 | 世界坐标系/局部坐标系,可自由旋转 |
用途 | 网页绘图、图形界面 | 路径规划、角色运动、摄像机轨迹、特效等 |
可视化 | 自动绘制曲线 | 需使用 Gizmos 或 LineRenderer |
四、总结
- 在 HTMLCanvas 中绘制贝塞尔曲线非常方便,因为有现成 API。
- 在 Unity3D 中则需要自己实现公式,但好处是可以自由操作 三维空间中的曲线,并将其应用于路径规划、动画和摄像机控制等复杂场景。
- 一旦理解了背后的数学原理,你会发现:2D 与 3D 的差异,其实就是坐标维度的不同。