1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use std::marker::PhantomData;
use bevy_app::Plugin;
use bevy_ecs::{prelude::*, schedule::StateData};
use bevy_egui::EguiPlugin;
use bevy_reflect::Reflect;
use pretty_type_name::pretty_type_name;
use crate::{bevy_inspector, DefaultInspectorConfigPlugin};
const DEFAULT_SIZE: (f32, f32) = (320., 160.);
pub struct WorldInspectorPlugin;
impl Plugin for WorldInspectorPlugin {
fn build(&self, app: &mut bevy_app::App) {
if !app.is_plugin_added::<DefaultInspectorConfigPlugin>() {
app.add_plugin(DefaultInspectorConfigPlugin);
}
if !app.is_plugin_added::<EguiPlugin>() {
app.add_plugin(EguiPlugin);
}
app.add_system(world_inspector_ui);
}
}
fn world_inspector_ui(world: &mut World) {
let egui_context = world
.resource_mut::<bevy_egui::EguiContext>()
.ctx_mut()
.clone();
egui::Window::new("World Inspector")
.default_size(DEFAULT_SIZE)
.show(&egui_context, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
bevy_inspector::ui_for_world(world, ui);
ui.allocate_space(ui.available_size());
});
});
}
pub struct ResourceInspectorPlugin<T>(PhantomData<fn() -> T>);
impl<T> Default for ResourceInspectorPlugin<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<T> ResourceInspectorPlugin<T> {
pub fn new() -> Self {
Self(PhantomData)
}
}
impl<T: Resource + Reflect> Plugin for ResourceInspectorPlugin<T> {
fn build(&self, app: &mut bevy_app::App) {
if !app.is_plugin_added::<DefaultInspectorConfigPlugin>() {
app.add_plugin(DefaultInspectorConfigPlugin);
}
if !app.is_plugin_added::<EguiPlugin>() {
app.add_plugin(EguiPlugin);
}
app.add_system(inspector_ui::<T>);
}
}
fn inspector_ui<T: Resource + Reflect>(world: &mut World) {
let egui_context = world
.resource_mut::<bevy_egui::EguiContext>()
.ctx_mut()
.clone();
egui::Window::new(pretty_type_name::<T>())
.default_size((0., 0.))
.show(&egui_context, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
bevy_inspector::ui_for_resource::<T>(world, ui);
ui.allocate_space(ui.available_size());
});
});
}
pub struct StateInspectorPlugin<T>(PhantomData<fn() -> T>);
impl<T> Default for StateInspectorPlugin<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<T> StateInspectorPlugin<T> {
pub fn new() -> Self {
Self(PhantomData)
}
}
impl<T: StateData + Reflect> Plugin for StateInspectorPlugin<T> {
fn build(&self, app: &mut bevy_app::App) {
if !app.is_plugin_added::<DefaultInspectorConfigPlugin>() {
app.add_plugin(DefaultInspectorConfigPlugin);
}
if !app.is_plugin_added::<EguiPlugin>() {
app.add_plugin(EguiPlugin);
}
app.add_system(state_ui::<T>);
}
}
fn state_ui<T: StateData + Reflect>(world: &mut World) {
let egui_context = world
.resource_mut::<bevy_egui::EguiContext>()
.ctx_mut()
.clone();
egui::Window::new(std::any::type_name::<T>())
.resizable(false)
.title_bar(false)
.show(&egui_context, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.heading(pretty_type_name::<T>());
bevy_inspector::ui_for_state::<T>(world, ui);
});
});
}