@@ -4,6 +4,7 @@ use bevy_asset::{load_internal_asset, Asset, Assets, Handle};
4
4
use bevy_ecs:: prelude:: * ;
5
5
use bevy_reflect:: { std_traits:: ReflectDefault , Reflect , TypePath , TypeUuid } ;
6
6
use bevy_render:: {
7
+ color:: Color ,
7
8
extract_resource:: ExtractResource ,
8
9
mesh:: { Mesh , MeshVertexBufferLayout } ,
9
10
prelude:: Shader ,
@@ -25,7 +26,6 @@ pub const WIREFRAME_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(19259
25
26
/// This is a native only feature.
26
27
#[ derive( Debug , Default ) ]
27
28
pub struct WireframePlugin ;
28
-
29
29
impl Plugin for WireframePlugin {
30
30
fn build ( & self , app : & mut bevy_app:: App ) {
31
31
load_internal_asset ! (
@@ -43,7 +43,12 @@ impl Plugin for WireframePlugin {
43
43
. add_systems ( Startup , setup_global_wireframe_material)
44
44
. add_systems (
45
45
Update ,
46
- ( apply_global_wireframe_material, apply_wireframe_material) ,
46
+ (
47
+ global_color_changed,
48
+ wireframe_color_changed,
49
+ apply_wireframe_material,
50
+ apply_global_wireframe_material,
51
+ ) ,
47
52
) ;
48
53
}
49
54
}
@@ -56,6 +61,17 @@ impl Plugin for WireframePlugin {
56
61
#[ reflect( Component , Default ) ]
57
62
pub struct Wireframe ;
58
63
64
+ /// Sets the color of the [`Wireframe`] of the entity it is attached to.
65
+ /// If this component is present but there's no [`Wireframe`] component,
66
+ /// it will still affect the color of the wireframe when [`WireframeConfig::global`] is set to true.
67
+ ///
68
+ /// This overrides the [`WireframeConfig::default_color`].
69
+ #[ derive( Component , Debug , Clone , Default , Reflect ) ]
70
+ #[ reflect( Component , Default ) ]
71
+ pub struct WireframeColor {
72
+ pub color : Color ,
73
+ }
74
+
59
75
/// Disables wireframe rendering for any entity it is attached to.
60
76
/// It will ignore the [`WireframeConfig`] global setting.
61
77
///
@@ -70,6 +86,10 @@ pub struct WireframeConfig {
70
86
/// Whether to show wireframes for all meshes.
71
87
/// Can be overridden for individual meshes by adding a [`Wireframe`] or [`NoWireframe`] component.
72
88
pub global : bool ,
89
+ /// If [`Self::global`] is set, any [`Entity`] that does not have a [`Wireframe`] component attached to it will have
90
+ /// wireframes using this color. Otherwise, this will be the fallback color for any entity that has a [`Wireframe`],
91
+ /// but no [`WireframeColor`].
92
+ pub default_color : Color ,
73
93
}
74
94
75
95
#[ derive( Resource ) ]
@@ -81,19 +101,56 @@ struct GlobalWireframeMaterial {
81
101
fn setup_global_wireframe_material (
82
102
mut commands : Commands ,
83
103
mut materials : ResMut < Assets < WireframeMaterial > > ,
104
+ config : Res < WireframeConfig > ,
84
105
) {
85
106
// Create the handle used for the global material
86
107
commands. insert_resource ( GlobalWireframeMaterial {
87
- handle : materials. add ( WireframeMaterial { } ) ,
108
+ handle : materials. add ( WireframeMaterial {
109
+ color : config. default_color ,
110
+ } ) ,
88
111
} ) ;
89
112
}
90
113
114
+ /// Updates the wireframe material of all entities without a [`WireframeColor`] or without a [`Wireframe`] component
115
+ fn global_color_changed (
116
+ config : Res < WireframeConfig > ,
117
+ mut materials : ResMut < Assets < WireframeMaterial > > ,
118
+ global_material : Res < GlobalWireframeMaterial > ,
119
+ ) {
120
+ if !config. is_changed ( ) {
121
+ return ;
122
+ }
123
+ if let Some ( global_material) = materials. get_mut ( & global_material. handle ) {
124
+ global_material. color = config. default_color ;
125
+ }
126
+ }
127
+
128
+ /// Updates the wireframe material when the color in [`WireframeColor`] changes
129
+ #[ allow( clippy:: type_complexity) ]
130
+ fn wireframe_color_changed (
131
+ mut materials : ResMut < Assets < WireframeMaterial > > ,
132
+ mut colors_changed : Query <
133
+ ( & mut Handle < WireframeMaterial > , & WireframeColor ) ,
134
+ ( With < Wireframe > , Changed < WireframeColor > ) ,
135
+ > ,
136
+ ) {
137
+ for ( mut handle, wireframe_color) in & mut colors_changed {
138
+ * handle = materials. add ( WireframeMaterial {
139
+ color : wireframe_color. color ,
140
+ } ) ;
141
+ }
142
+ }
143
+
91
144
/// Applies or remove the wireframe material to any mesh with a [`Wireframe`] component.
92
145
fn apply_wireframe_material (
93
146
mut commands : Commands ,
94
147
mut materials : ResMut < Assets < WireframeMaterial > > ,
95
- wireframes : Query < Entity , ( With < Wireframe > , Without < Handle < WireframeMaterial > > ) > ,
148
+ wireframes : Query <
149
+ ( Entity , Option < & WireframeColor > ) ,
150
+ ( With < Wireframe > , Without < Handle < WireframeMaterial > > ) ,
151
+ > ,
96
152
mut removed_wireframes : RemovedComponents < Wireframe > ,
153
+ global_material : Res < GlobalWireframeMaterial > ,
97
154
) {
98
155
for e in removed_wireframes. read ( ) {
99
156
if let Some ( mut commands) = commands. get_entity ( e) {
@@ -102,8 +159,16 @@ fn apply_wireframe_material(
102
159
}
103
160
104
161
let mut wireframes_to_spawn = vec ! [ ] ;
105
- for e in & wireframes {
106
- wireframes_to_spawn. push ( ( e, materials. add ( WireframeMaterial { } ) ) ) ;
162
+ for ( e, wireframe_color) in & wireframes {
163
+ let material = if let Some ( wireframe_color) = wireframe_color {
164
+ materials. add ( WireframeMaterial {
165
+ color : wireframe_color. color ,
166
+ } )
167
+ } else {
168
+ // If there's no color specified we can use the global material since it's already set to use the default_color
169
+ global_material. handle . clone ( )
170
+ } ;
171
+ wireframes_to_spawn. push ( ( e, material) ) ;
107
172
}
108
173
commands. insert_or_spawn_batch ( wireframes_to_spawn) ;
109
174
}
@@ -154,7 +219,10 @@ fn apply_global_wireframe_material(
154
219
155
220
#[ derive( Default , AsBindGroup , TypeUuid , TypePath , Debug , Clone , Asset ) ]
156
221
#[ uuid = "9e694f70-9963-4418-8bc1-3474c66b13b8" ]
157
- struct WireframeMaterial { }
222
+ struct WireframeMaterial {
223
+ #[ uniform( 0 ) ]
224
+ pub color : Color ,
225
+ }
158
226
159
227
impl Material for WireframeMaterial {
160
228
fn fragment_shader ( ) -> ShaderRef {
0 commit comments