Rust插件库bevy-inspector-egui-derive的使用:Bevy引擎的实时属性检查与调试工具

Rust插件库bevy-inspector-egui-derive的使用:Bevy引擎的实时属性检查与调试工具

快速插件使用

WorldInspectorPlugin

显示世界中的实体、资源和资产。

use bevy::prelude::*;
use bevy_inspector_egui::quick::WorldInspectorPlugin;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(EguiPlugin::default())
        .add_plugins(WorldInspectorPlugin::new())
        .run();
}

ResourceInspectorPlugin

在窗口中显示单个资源。

use bevy::prelude::*;
use bevy_inspector_egui::prelude::*;
use bevy_inspector_egui::quick::ResourceInspectorPlugin;

// `InspectorOptions` 是完全可选的
#[derive(Reflect, Resource, Default, InspectorOptions)]
#[reflect(Resource, InspectorOptions)]
struct Configuration {
    name: String,
    #[inspector(min = 0.0, max = 1.0)]
    option: f32,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_resource::<Configuration>() // `ResourceInspectorPlugin` 不会初始化资源
        .register_type::<Configuration>() // 需要注册类型才能显示
        .add_plugins(EguiPlugin::default())
        .add_plugins(ResourceInspectorPlugin::<Configuration>::default())
        // 也适用于内置资源,只要它们是 `Reflect`
        .add_plugins(ResourceInspectorPlugin::<Time>::default())
        .run();
}

手动UI

快速插件不允许自定义egui窗口或其内容,但您可以轻松构建自己的UI:

use bevy::prelude::*;
use bevy_egui::EguiPlugin;
use bevy_inspector_egui::prelude::*;
use std::any::TypeId;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(EguiPlugin::default())
        .add_plugins(bevy_inspector_egui::DefaultInspectorConfigPlugin) // 添加默认选项和 `InspectorEguiImpl`s
        .add_systems(EguiPrimaryContextPass, inspector_ui)
        .run();
}

fn inspector_ui(world: &mut World) {
    let Ok(egui_context) = world
        .query_filtered::<&mut EguiContext, With<PrimaryEguiContext>>()
        .get_single(world)
    else {
        return;
    };
    let mut egui_context = egui_context.clone();

    egui::Window::new("UI").show(egui_context.get_mut(), |ui| {
        egui::ScrollArea::vertical().show(ui, |ui| {
            // 等同于 `WorldInspectorPlugin`
            bevy_inspector_egui::bevy_inspector::ui_for_world(world, ui);

            egui::CollapsingHeader::new("Materials").show(ui, |ui| {
                bevy_inspector_egui::bevy_inspector::ui_for_assets::<StandardMaterial>(world, ui);
            });

            ui.heading("Entities");
            bevy_inspector_egui::bevy_inspector::ui_for_world_entities(world, ui);
        });
    });
}

完整示例代码

use bevy::prelude::*;
use bevy_inspector_egui::quick::{WorldInspectorPlugin, ResourceInspectorPlugin};
use bevy_inspector_egui::prelude::*;

// 自定义资源结构体
#[derive(Reflect, Resource, Default, InspectorOptions)]
#[reflect(Resource, InspectorOptions)]
struct GameConfig {
    player_name: String,
    #[inspector(min = 0.0, max = 100.0)]
    difficulty: f32,
    #[inspector(min = 1, max = 10)]
    level: usize,
    is_paused: bool,
}

fn main() {
    App::new()
        // 添加默认插件
        .add_plugins(DefaultPlugins)
        
        // 添加egui插件
        .add_plugins(EguiPlugin::default())
        
        // 初始化我们的自定义资源
        .init_resource::<GameConfig>()
        
        // 注册类型以便显示
        .register_type::<GameConfig>()
        
        // 添加世界检查器插件
        .add_plugins(WorldInspectorPlugin::new())
        
        // 添加资源检查器插件来显示我们的GameConfig
        .add_plugins(ResourceInspectorPlugin::<GameConfig>::default())
        
        // 添加资源检查器插件来显示内置的Time资源
        .add_plugins(ResourceInspectorPlugin::<Time>::default())
        
        // 启动应用
        .run();
}

常见问题解答

Q: 如何更改世界检查器中实体的名称?

A: 您可以插入 Name 组件。

Q: 如果我只想显示单个值而不传入整个 &mut World 怎么办?

A: 您可以使用 reflect_inspector::ui_for_value。注意,像 Handle<StandardMaterial> 这样的东西将无法显示资产的值。

Q: 我可以更改我的类型的显示方式吗?

A: 实现 InspectorPrimitive 并调用 app.register_type_data::<T, InspectorEguiImpl>

Bevy支持表

bevy bevy-inspector-egui
0.16 0.33
0.16 0.32
0.16 0.31
0.15 0.30
0.15 0.29
0.15 0.28
0.14 0.27
0.14 0.26
0.14 0.25
0.13 0.24
0.13 0.23
0.12 0.22
0.12 0.21
0.11 0.19-0.20
0.10 0.18
0.9 0.14-0.17
0.8 0.12-0.13
0.7 0.10-0.11
0.6 0.9
0.6 0.8
0.6 0.7
0.5 0.5-0.6
0.5 0.4
0.4 0.1-0.3

1 回复

bevy-inspector-egui-derive:Bevy引擎的实时属性检查与调试工具

bevy-inspector-egui-derive 是一个用于 Bevy 游戏引擎的插件,它提供了实时的属性检查和调试功能,通过 egui 实现了一个可视化界面,让你可以在游戏运行时查看和修改组件、资源和系统的属性。

主要功能

  1. 实时查看和编辑 Bevy 实体、组件和资源的属性
  2. 支持嵌套结构体的可视化编辑
  3. 提供自定义属性检查器的能力
  4. 与 Bevy 的 ECS 系统无缝集成

安装方法

Cargo.toml 中添加以下依赖:

[dependencies]
bevy = "0.11"
bevy-inspector-egui = "0.19"
bevy-inspector-egui-derive = "0.19"

完整示例代码

下面是一个完整的示例,展示了如何使用 bevy-inspector-egui-derive 来检查和修改游戏中的实体和资源:

use bevy::prelude::*;
use bevy_inspector_egui::prelude::*;
use bevy_inspector_egui::WorldInspectorPlugin;

// 定义可检查的玩家组件
#[derive(Component, Inspectable, Default)]
struct Player {
    name: String,
    health: f32,
    stamina: f32,
    #[inspectable(min = 0.0, max = 100.0)]
    level: u32,
    inventory: Vec<Item>,
}

// 定义可检查的物品结构体
#[derive(Inspectable, Default)]
struct Item {
    name: String,
    #[inspectable(min = 0.1, max = 10.0)]
    weight: f32,
    value: u32,
}

// 定义可检查的游戏设置资源
#[derive(Inspectable, Default)]
struct GameSettings {
    #[inspectable(label = "游戏难度")]
    difficulty: f32,
    #[inspectable(label = "显示FPS")]
    show_fps: bool,
    #[inspectable(min = 0.0, max = 1.0)]
    master_volume: f32,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        // 添加世界检查器插件
        .add_plugin(WorldInspectorPlugin::new())
        // 添加游戏设置资源
        .insert_resource(GameSettings {
            difficulty: 0.5,
            show_fps: true,
            master_volume: 0.7,
        })
        .add_startup_system(setup)
        // 添加自定义调试窗口系统
        .add_system(player_debug_system)
        .run();
}

// 初始化系统 - 创建玩家实体
fn setup(mut commands: Commands) {
    commands.spawn((
        Player {
            name: "英雄".to_string(),
            health: 100.0,
            stamina: 50.0,
            level: 1,
            inventory: vec![
                Item {
                    name: "长剑".to_string(),
                    weight: 3.5,
                    value: 100,
                },
                Item {
                    name: "盾牌".to_string(),
                    weight: 5.0,
                    value: 75,
                },
            ],
        },
        Name::new("玩家实体"),
    ));
}

// 自定义调试窗口系统
fn player_debug_system(
    query: Query<&Player>,
    mut contexts: EguiContexts,
) {
    egui::Window::new("玩家状态").show(contexts.ctx_mut(), |ui| {
        for player in query.iter() {
            ui.label(format!("名称: {}", player.name));
            ui.label(format!("生命值: {:.1}", player.health));
            ui.label(format!("耐力: {:.1}", player.stamina));
            ui.label(format!("等级: {}", player.level));
            
            ui.separator();
            ui.label("物品栏:");
            for item in &player.inventory {
                ui.label(format!("- {} (重量: {}, 价值: {})", 
                    item.name, item.weight, item.value));
            }
        }
    });
}

代码说明

  1. 组件定义

    • 使用 #[derive(Inspectable)] 派生宏使结构体可在检查器中显示
    • 通过 #[inspectable] 属性添加额外的检查器配置
  2. 资源检查

    • 使用 insert_resource 添加可检查的资源
    • 资源会自动出现在检查器的资源选项卡中
  3. 自定义检查器

    • 实现了自定义的 player_debug_system 系统
    • 使用 egui 创建了一个显示玩家状态的独立窗口
  4. 实体检查

    • 通过 WorldInspectorPlugin 添加的检查器可以查看场景中的所有实体
    • 可以实时修改组件的属性值

运行效果

运行此示例后,你将看到:

  1. 主检查器窗口(通过 WorldInspectorPlugin 添加)
  2. 自定义的"玩家状态"调试窗口
  3. 可以实时修改玩家属性和游戏设置

注意事项

  1. 确保所有相关依赖版本兼容
  2. 在开发完成后,建议移除检查器插件以减少发布版本的体积
  3. 对于复杂项目,检查器可能会影响性能,建议仅在开发时使用
回到顶部