自定义诊断
bevy_diagnostic 提供了 Diagnostic 系统,用于跟踪随时间变化的数值指标——帧率、内存使用、实体数量等。
注册诊断路径
每个指标通过一个 DiagnosticPath 标识。路径用 / 分隔,不能以 / 开头或结尾:
rust
use bevy::diagnostic::{
Diagnostic, DiagnosticPath, Diagnostics, DiagnosticsPlugin, RegisterDiagnostic,
};
use bevy::prelude::*;
const ENTITY_COUNT_PATH: DiagnosticPath = DiagnosticPath::const_new("custom/entity_count");
fn main() {
App::new()
.add_plugins((DefaultPlugins, DiagnosticsPlugin))
.register_diagnostic(Diagnostic::new(ENTITY_COUNT_PATH))
.add_systems(Startup, setup)
.add_systems(Update, (spawn_entities, count_entities))
.run();
}
#[derive(Component)]
struct Marker;
fn setup(mut commands: Commands) {
commands.spawn(Camera2d);
info!("自定义诊断示例:每秒统计一次实体数量");
}
fn spawn_entities(
mut commands: Commands,
keyboard: Res<ButtonInput<KeyCode>>,
existing: Query<Entity, With<Marker>>,
) {
if keyboard.just_pressed(KeyCode::Space) {
for _ in 0..10 {
commands.spawn(Marker);
}
info!(" spawned 10 个 Marker,现有 {}", existing.iter().count() + 10);
}
}
fn count_entities(
query: Query<Entity, With<Marker>>,
mut diagnostics: Diagnostics,
time: Res<Time>,
mut accumulator: Local<f32>,
) {
*accumulator += time.delta_secs();
if *accumulator >= 1.0 {
*accumulator -= 1.0;
let count = query.iter().count() as f64;
diagnostics.add_measurement(&ENTITY_COUNT_PATH, || count);
info!("当前 Marker 实体数: {count}");
}
}Listing 33-4:自定义诊断——统计 Marker 实体数量
DiagnosticPath::const_new 可以在 const 上下文中使用,适合定义在模块顶层。register_diagnostic 在 App 上注册后,DiagnosticsStore 资源会自动初始化。
写入测量值
Diagnostics 是一个 SystemParam,提供 add_measurement 方法:
rust
diagnostics.add_measurement(&MY_PATH, || expensive_computation() as f64);闭包只在诊断启用时才求值——如果不需要计算开销,这避免了无谓的浪费。
读取诊断值
DiagnosticsStore 资源存储了所有诊断的历史数据。可以读取:
get(&path):获取Diagnostic对象,包含历史记录、平均值get_measurement(&path):获取最新一次测量值measurement():返回Option<&DiagnosticMeasurement>,含time和value
Diagnostic 还维护了一个指数移动平均(EMA),平滑因子默认为 2/21。可以通过 with_max_history_length 调整历史深度。
内置诊断
Bevy 内置了一些诊断插件:
FrameTimeDiagnosticsPlugin:帧时间、FPS、帧计数LogDiagnosticsPlugin:定期把诊断值输出到日志EntityCountDiagnosticsPlugin:实体总数SystemInformationDiagnosticsPlugin:CPU / 内存使用
它们都通过 DiagnosticsPlugin 注册。你可以在同一 App 中同时使用内置和自定义诊断。