Gizmos:即时模式画线
Gizmos 是 Bevy 内置的调试绘图系统——你写一个系统、拿到 Gizmos 系统参数、调方法画线,下一帧线就出现在屏幕上,再下一帧就没了。这就是"即时模式"(immediate mode):每帧重新提交,不存状态。
它不需要加载模型、不需要材质、不需要 UV——只要一行代码,一条线就出来了。适合做碰撞体可视化、路径调试、射线检测显示、坐标轴指示等一切"开发时才看得到、发布时自动消失"的辅助画面。
第一条线
gizmos.line(Vec3::ZERO, Vec3::new(2., 1., 0.), Color::WHITE);Gizmos 是一个系统参数,和 Query、Res 一样直接出现在函数签名里。line 接受起点、终点和颜色。颜色可以是 Color::WHITE、Color::srgb(...),也可以是 bevy::color::palettes::css 里的常量。
球、箭头、射线
Gizmos 提供了丰富的图元方法:
gizmos.sphere(Vec3::new(-2., 1., 0.), 0.8, Color::srgb(0.9, 0.3, 0.3));sphere 画一个线框球,参数是中心、半径和颜色。默认 32 段线段,调 .resolution(n) 可以改。
gizmos.arrow(
Vec3::new(0., 0.1, 0.),
Vec3::new(ops::cos(t) * 2., 1.5, ops::sin(t) * 2.),
Color::srgb(0.2, 0.8, 0.2),
);arrow 画带箭头的线段,从起点指向终点。箭头方向自动推算——非常适合可视化朝向、力的方向。
gizmos.ray(
Vec3::new(2., 0.5, 0.),
Vec3::new(-1., ops::sin(t * 2.) * 0.5, 0.),
Color::srgb(0.3, 0.5, 0.9),
);ray 和 arrow 类似,但第二个参数是方向向量而非终点——射线从起点沿方向无限延伸(视觉上是一段足够长的线)。这个例子让方向随时间摆动,你可以直观看到"方向向量"和"终点位置"的区别。
网格参考线
gizmos.grid(
Quat::from_rotation_x(PI / 2.),
UVec2::splat(10),
Vec2::splat(1.),
Color::srgb(0.25, 0.25, 0.25),
);grid 画一个平面网格,参数依次是旋转(四元数)、行列数、格子间距和颜色。把旋转设为绕 X 轴 90° 就是一个水平地面参考网格。对于需要对齐物体摆放的场景非常实用。
完整示例
use bevy::prelude::*;
use std::f32::consts::PI;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, draw_gizmos)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn((
Camera3d::default(),
Transform::from_xyz(0., 2.5, 6.).looking_at(Vec3::ZERO, Vec3::Y),
));
commands.spawn((
PointLight::default(),
Transform::from_xyz(4.0, 8.0, 4.0),
));
}
fn draw_gizmos(mut gizmos: Gizmos, time: Res<Time>) {
let t = time.elapsed_secs();
// ANCHOR: line
gizmos.line(Vec3::ZERO, Vec3::new(2., 1., 0.), Color::WHITE);
// ANCHOR_END: line
// ANCHOR: sphere
gizmos.sphere(Vec3::new(-2., 1., 0.), 0.8, Color::srgb(0.9, 0.3, 0.3));
// ANCHOR_END: sphere
// ANCHOR: arrow
gizmos.arrow(
Vec3::new(0., 0.1, 0.),
Vec3::new(ops::cos(t) * 2., 1.5, ops::sin(t) * 2.),
Color::srgb(0.2, 0.8, 0.2),
);
// ANCHOR_END: arrow
// ANCHOR: ray
gizmos.ray(
Vec3::new(2., 0.5, 0.),
Vec3::new(-1., ops::sin(t * 2.) * 0.5, 0.),
Color::srgb(0.3, 0.5, 0.9),
);
// ANCHOR_END: ray
// ANCHOR: grid
gizmos.grid(
Quat::from_rotation_x(PI / 2.),
UVec2::splat(10),
Vec2::splat(1.),
Color::srgb(0.25, 0.25, 0.25),
);
// ANCHOR_END: grid
}Listing 27-1:基础 Gizmos——线、球、箭头、射线、网格
运行:
cargo run -p ch27-devtools --example listing-27-01你会看到一个 3D 场景:一条白线、一个红球、一支随时间旋转的绿箭头、一条摆动的蓝射线,以及铺在地面上的灰色网格。箭头和射线每帧更新位置——因为 Gizmos 是即时模式,每帧重新画就是"动起来"的全部秘密。
2D 与 3D 的分野
Gizmos 同时支持 2D 和 3D,方法名带 _2d 后缀的是 2D 版本:
| 3D 方法 | 2D 方法 | 说明 |
|---|---|---|
line | line_2d | 线段 |
ray | ray_2d | 射线 |
rect | rect_2d | 矩形 |
circle | circle_2d | 圆 |
arrow | arrow_2d | 箭头 |
2D 版本接受 Vec2 而非 Vec3,绘制在 2D 相机的平面上。下一节会把 2D 和 3D 图元放在一起展示。