Trait bevy::ecs::prelude::IntoSystemConfigs

pub trait IntoSystemConfigs<Marker>: Sized {
    // Required method
    fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>;

    // Provided methods
    fn in_set(
        self,
        set: impl SystemSet,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn before<M>(
        self,
        set: impl IntoSystemSet<M>,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn after<M>(
        self,
        set: impl IntoSystemSet<M>,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn before_ignore_deferred<M>(
        self,
        set: impl IntoSystemSet<M>,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn after_ignore_deferred<M>(
        self,
        set: impl IntoSystemSet<M>,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn distributive_run_if<M>(
        self,
        condition: impl Condition<M> + Clone,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn run_if<M>(
        self,
        condition: impl Condition<M>,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn ambiguous_with<M>(
        self,
        set: impl IntoSystemSet<M>,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn ambiguous_with_all(
        self,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn chain(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
    fn chain_ignore_deferred(
        self,
    ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>> { ... }
}
Expand description

Types that can convert into a SystemConfigs.

This trait is implemented for “systems” (functions whose arguments all implement SystemParam), or tuples thereof. It is a common entry point for system configurations.

§Examples


fn handle_input() {}

fn update_camera() {}
fn update_character() {}

app.add_systems(
    Update,
    (
        handle_input,
        (update_camera, update_character).after(handle_input)
    )
);

Required Methods§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Convert into a SystemConfigs.

Provided Methods§

fn in_set( self, set: impl SystemSet, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Add these systems to the provided set.

Examples found in repository?
examples/stress_tests/many_lights.rs (line 164)
159
160
161
162
163
164
165
    fn build(&self, app: &mut App) {
        let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
            return;
        };

        render_app.add_systems(Render, print_visible_light_count.in_set(RenderSet::Prepare));
    }
More examples
Hide additional examples
examples/shader/shader_instancing.rs (line 94)
86
87
88
89
90
91
92
93
94
95
96
97
98
    fn build(&self, app: &mut App) {
        app.add_plugins(ExtractComponentPlugin::<InstanceMaterialData>::default());
        app.sub_app_mut(RenderApp)
            .add_render_command::<Transparent3d, DrawCustom>()
            .init_resource::<SpecializedMeshPipelines<CustomPipeline>>()
            .add_systems(
                Render,
                (
                    queue_custom.in_set(RenderSet::QueueMeshes),
                    prepare_instance_buffers.in_set(RenderSet::PrepareResources),
                ),
            );
    }
examples/shader/compute_shader_game_of_life.rs (line 110)
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    fn build(&self, app: &mut App) {
        // Extract the game of life image resource from the main world into the render world
        // for operation on by the compute shader and display on the sprite.
        app.add_plugins(ExtractResourcePlugin::<GameOfLifeImages>::default());
        let render_app = app.sub_app_mut(RenderApp);
        render_app.add_systems(
            Render,
            prepare_bind_group.in_set(RenderSet::PrepareBindGroups),
        );

        let mut render_graph = render_app.world_mut().resource_mut::<RenderGraph>();
        render_graph.add_node(GameOfLifeLabel, GameOfLifeNode::default());
        render_graph.add_node_edge(GameOfLifeLabel, bevy::render::graph::CameraDriverLabel);
    }
examples/2d/mesh2d_manual.rs (line 299)
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
    fn build(&self, app: &mut App) {
        // Load our custom shader
        let mut shaders = app.world_mut().resource_mut::<Assets<Shader>>();
        shaders.insert(
            &COLORED_MESH2D_SHADER_HANDLE,
            Shader::from_wgsl(COLORED_MESH2D_SHADER, file!()),
        );

        // Register our custom draw function, and add our render systems
        app.get_sub_app_mut(RenderApp)
            .unwrap()
            .add_render_command::<Transparent2d, DrawColoredMesh2d>()
            .init_resource::<SpecializedRenderPipelines<ColoredMesh2dPipeline>>()
            .init_resource::<RenderColoredMesh2dInstances>()
            .add_systems(
                ExtractSchedule,
                extract_colored_mesh2d.after(extract_mesh2d),
            )
            .add_systems(Render, queue_colored_mesh2d.in_set(RenderSet::QueueMeshes));
    }
examples/shader/gpu_readback.rs (line 79)
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
    fn finish(&self, app: &mut App) {
        let (s, r) = crossbeam_channel::unbounded();
        app.insert_resource(MainWorldReceiver(r));

        let render_app = app.sub_app_mut(RenderApp);
        render_app
            .insert_resource(RenderWorldSender(s))
            .init_resource::<ComputePipeline>()
            .init_resource::<Buffers>()
            .add_systems(
                Render,
                (
                    prepare_bind_group
                        .in_set(RenderSet::PrepareBindGroups)
                        // We don't need to recreate the bind group every frame
                        .run_if(not(resource_exists::<GpuBufferBindGroup>)),
                    // We need to run it after the render graph is done
                    // because this needs to happen after submit()
                    map_and_read_buffer.after(RenderSet::Render),
                ),
            );

        // Add the compute node as a top level node to the render graph
        // This means it will only execute once per frame
        render_app
            .world_mut()
            .resource_mut::<RenderGraph>()
            .add_node(ComputeNodeLabel, ComputeNode::default());
    }
examples/state/custom_transitions.rs (line 78)
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
        fn build(&self, app: &mut App) {
            app.add_systems(
                StateTransition,
                // The internals can generate at most one transition event of specific type per frame.
                // We take the latest one and clear the queue.
                last_transition::<S>
                    // We insert the optional event into our schedule runner.
                    .pipe(run_reenter::<S>)
                    // State transitions are handled in three ordered steps, exposed as system sets.
                    // We can add our systems to them, which will run the corresponding schedules when they're evaluated.
                    // These are:
                    // - [`ExitSchedules`] - Ran from leaf-states to root-states,
                    // - [`TransitionSchedules`] - Ran in arbitrary order,
                    // - [`EnterSchedules`] - Ran from root-states to leaf-states.
                    .in_set(EnterSchedules::<S>::default()),
            )
            .add_systems(
                StateTransition,
                last_transition::<S>
                    .pipe(run_reexit::<S>)
                    .in_set(ExitSchedules::<S>::default()),
            );
        }

fn before<M>( self, set: impl IntoSystemSet<M>, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Runs before all systems in set. If self has any systems that produce Commands or other Deferred operations, all systems in set will see their effect.

If automatically inserting apply_deferred like this isn’t desired, use before_ignore_deferred instead.

Note: The given set is not implicitly added to the schedule when this system set is added. It is safe, but no dependencies will be created.

Examples found in repository?
examples/animation/animated_fox.rs (line 20)
12
13
14
15
16
17
18
19
20
21
22
23
fn main() {
    App::new()
        .insert_resource(AmbientLight {
            color: Color::WHITE,
            brightness: 2000.,
        })
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, setup_scene_once_loaded.before(animate_targets))
        .add_systems(Update, keyboard_animation_control)
        .run();
}
More examples
Hide additional examples
examples/animation/animation_graph.rs (line 88)
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
fn main() {
    #[cfg(not(target_arch = "wasm32"))]
    let args: Args = argh::from_env();
    #[cfg(target_arch = "wasm32")]
    let args = Args::from_args(&[], &[]).unwrap();

    App::new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                title: "Bevy Animation Graph Example".into(),
                ..default()
            }),
            ..default()
        }))
        .add_systems(Startup, (setup_assets, setup_scene, setup_ui))
        .add_systems(Update, init_animations.before(animate_targets))
        .add_systems(
            Update,
            (handle_weight_drag, update_ui, sync_weights).chain(),
        )
        .insert_resource(args)
        .insert_resource(AmbientLight {
            color: WHITE.into(),
            brightness: 100.0,
        })
        .run();
}

fn after<M>( self, set: impl IntoSystemSet<M>, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Run after all systems in set. If set has any systems that produce Commands or other Deferred operations, all systems in self will see their effect.

If automatically inserting apply_deferred like this isn’t desired, use after_ignore_deferred instead.

Note: The given set is not implicitly added to the schedule when this system set is added. It is safe, but no dependencies will be created.

Examples found in repository?
examples/tools/scene_viewer/morph_viewer_plugin.rs (line 285)
279
280
281
282
283
284
285
286
287
288
    fn build(&self, app: &mut App) {
        app.add_systems(
            Update,
            (
                update_morphs,
                detect_morphs,
                update_text.after(update_morphs),
            ),
        );
    }
More examples
Hide additional examples
examples/3d/skybox.rs (line 47)
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(CameraControllerPlugin)
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (
                cycle_cubemap_asset,
                asset_loaded.after(cycle_cubemap_asset),
                animate_light_direction,
            ),
        )
        .run();
}
examples/ecs/one_shot_systems.rs (line 24)
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(
            Startup,
            (
                setup_ui,
                setup_with_commands,
                setup_with_world.after(setup_ui), // since we run `system_b` once in world it needs to run after `setup_ui`
            ),
        )
        .add_systems(Update, (trigger_system, evaluate_callbacks).chain())
        .run();
}
examples/ui/ui_scaling.rs (line 22)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(TextSettings {
            allow_dynamic_font_size: true,
            ..default()
        })
        .insert_resource(TargetScale {
            start_scale: 1.0,
            target_scale: 1.0,
            target_time: Timer::new(Duration::from_millis(SCALE_TIME), TimerMode::Once),
        })
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (change_scaling, apply_scaling.after(change_scaling)),
        )
        .run();
}
examples/3d/reflection_probes.rs (line 75)
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
fn main() {
    // Create the app.
    App::new()
        .add_plugins(DefaultPlugins)
        .init_resource::<AppStatus>()
        .init_resource::<Cubemaps>()
        .add_systems(Startup, setup)
        .add_systems(PreUpdate, add_environment_map_to_camera)
        .add_systems(Update, change_reflection_type)
        .add_systems(Update, toggle_rotation)
        .add_systems(
            Update,
            rotate_camera
                .after(toggle_rotation)
                .after(change_reflection_type),
        )
        .add_systems(Update, update_text.after(rotate_camera))
        .run();
}
examples/app/headless_renderer.rs (line 218)
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    fn build(&self, app: &mut App) {
        let (s, r) = crossbeam_channel::unbounded();

        let render_app = app
            .insert_resource(MainWorldReceiver(r))
            .sub_app_mut(RenderApp);

        let mut graph = render_app.world_mut().resource_mut::<RenderGraph>();
        graph.add_node(ImageCopy, ImageCopyDriver);
        graph.add_node_edge(bevy::render::graph::CameraDriverLabel, ImageCopy);

        render_app
            .insert_resource(RenderWorldSender(s))
            // Make ImageCopiers accessible in RenderWorld system and plugin
            .add_systems(ExtractSchedule, image_copy_extract)
            // Receives image data from buffer to channel
            // so we need to run it after the render graph is done
            .add_systems(Render, receive_image_from_buffer.after(RenderSet::Render));
    }

fn before_ignore_deferred<M>( self, set: impl IntoSystemSet<M>, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Run before all systems in set.

Unlike before, this will not cause the systems in set to wait for the deferred effects of self to be applied.

fn after_ignore_deferred<M>( self, set: impl IntoSystemSet<M>, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Run after all systems in set.

Unlike after, this will not wait for the deferred effects of systems in set to be applied.

fn distributive_run_if<M>( self, condition: impl Condition<M> + Clone, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Add a run condition to each contained system.

Each system will receive its own clone of the Condition and will only run if the Condition is true.

Each individual condition will be evaluated at most once (per schedule run), right before the corresponding system prepares to run.

This is equivalent to calling run_if on each individual system, as shown below:

schedule.add_systems((a, b).distributive_run_if(condition));
schedule.add_systems((a.run_if(condition), b.run_if(condition)));
§Note

Because the conditions are evaluated separately for each system, there is no guarantee that all evaluations in a single schedule run will yield the same result. If another system is run inbetween two evaluations it could cause the result of the condition to change.

Use run_if on a SystemSet if you want to make sure that either all or none of the systems are run, or you don’t want to evaluate the run condition for each contained system separately.

fn run_if<M>( self, condition: impl Condition<M>, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Run the systems only if the Condition is true.

The Condition will be evaluated at most once (per schedule run), the first time a system in this set prepares to run.

If this set contains more than one system, calling run_if is equivalent to adding each system to a common set and configuring the run condition on that set, as shown below:

§Examples
schedule.add_systems((a, b).run_if(condition));
schedule.add_systems((a, b).in_set(C)).configure_sets(C.run_if(condition));
§Note

Because the condition will only be evaluated once, there is no guarantee that the condition is upheld after the first system has run. You need to make sure that no other systems that could invalidate the condition are scheduled inbetween the first and last run system.

Use distributive_run_if if you want the condition to be evaluated for each individual system, right before one is run.

Examples found in repository?
examples/2d/texture_atlas.rs (line 17)
12
13
14
15
16
17
18
19
20
fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // fallback to nearest sampling
        .init_state::<AppState>()
        .add_systems(OnEnter(AppState::Setup), load_textures)
        .add_systems(Update, check_textures.run_if(in_state(AppState::Setup)))
        .add_systems(OnEnter(AppState::Finished), setup)
        .run();
}
More examples
Hide additional examples
examples/tools/scene_viewer/scene_viewer_plugin.rs (line 76)
68
69
70
71
72
73
74
75
76
77
78
79
    fn build(&self, app: &mut App) {
        app.init_resource::<CameraTracker>()
            .add_systems(PreUpdate, scene_load_check)
            .add_systems(
                Update,
                (
                    update_lights,
                    camera_tracker,
                    toggle_bounding_boxes.run_if(input_just_pressed(KeyCode::KeyB)),
                ),
            );
    }
examples/ui/overflow_debug.rs (line 17)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_resource::<AnimationState>()
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (
                toggle_overflow.run_if(input_just_pressed(KeyCode::KeyO)),
                next_container_size.run_if(input_just_pressed(KeyCode::KeyS)),
                update_transform::<Move>,
                update_transform::<Scale>,
                update_transform::<Rotate>,
                update_animation,
            ),
        )
        .run();
}
examples/math/custom_primitives.rs (line 102)
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_state::<BoundingShape>()
        .init_state::<CameraActive>()
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (
                (rotate_2d_shapes, bounding_shapes_2d).run_if(in_state(CameraActive::Dim2)),
                (rotate_3d_shapes, bounding_shapes_3d).run_if(in_state(CameraActive::Dim3)),
                update_bounding_shape.run_if(input_just_pressed(KeyCode::KeyB)),
                switch_cameras.run_if(input_just_pressed(KeyCode::Space)),
            ),
        )
        .run();
}
examples/games/game_menu.rs (line 60)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
    pub fn splash_plugin(app: &mut App) {
        // As this plugin is managing the splash screen, it will focus on the state `GameState::Splash`
        app
            // When entering the state, spawn everything needed for this screen
            .add_systems(OnEnter(GameState::Splash), splash_setup)
            // While in this state, run the `countdown` system
            .add_systems(Update, countdown.run_if(in_state(GameState::Splash)))
            // When exiting the state, despawn everything that was spawned for this screen
            .add_systems(OnExit(GameState::Splash), despawn_screen::<OnSplashScreen>);
    }

    // Tag component used to tag entities added on the splash screen
    #[derive(Component)]
    struct OnSplashScreen;

    // Newtype to use a `Timer` for this screen as a resource
    #[derive(Resource, Deref, DerefMut)]
    struct SplashTimer(Timer);

    fn splash_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
        let icon = asset_server.load("branding/icon.png");
        // Display the logo
        commands
            .spawn((
                NodeBundle {
                    style: Style {
                        align_items: AlignItems::Center,
                        justify_content: JustifyContent::Center,
                        width: Val::Percent(100.0),
                        height: Val::Percent(100.0),
                        ..default()
                    },
                    ..default()
                },
                OnSplashScreen,
            ))
            .with_children(|parent| {
                parent.spawn(ImageBundle {
                    style: Style {
                        // This will set the logo to be 200px wide, and auto adjust its height
                        width: Val::Px(200.0),
                        ..default()
                    },
                    image: UiImage::new(icon),
                    ..default()
                });
            });
        // Insert the timer as a resource
        commands.insert_resource(SplashTimer(Timer::from_seconds(1.0, TimerMode::Once)));
    }

    // Tick the timer, and change state when finished
    fn countdown(
        mut game_state: ResMut<NextState<GameState>>,
        time: Res<Time>,
        mut timer: ResMut<SplashTimer>,
    ) {
        if timer.tick(time.delta()).finished() {
            game_state.set(GameState::Menu);
        }
    }
}

mod game {
    use bevy::{
        color::palettes::basic::{BLUE, LIME},
        prelude::*,
    };

    use super::{despawn_screen, DisplayQuality, GameState, Volume, TEXT_COLOR};

    // This plugin will contain the game. In this case, it's just be a screen that will
    // display the current settings for 5 seconds before returning to the menu
    pub fn game_plugin(app: &mut App) {
        app.add_systems(OnEnter(GameState::Game), game_setup)
            .add_systems(Update, game.run_if(in_state(GameState::Game)))
            .add_systems(OnExit(GameState::Game), despawn_screen::<OnGameScreen>);
    }

    // Tag component used to tag entities added on the game screen
    #[derive(Component)]
    struct OnGameScreen;

    #[derive(Resource, Deref, DerefMut)]
    struct GameTimer(Timer);

    fn game_setup(
        mut commands: Commands,
        display_quality: Res<DisplayQuality>,
        volume: Res<Volume>,
    ) {
        commands
            .spawn((
                NodeBundle {
                    style: Style {
                        width: Val::Percent(100.0),
                        height: Val::Percent(100.0),
                        // center children
                        align_items: AlignItems::Center,
                        justify_content: JustifyContent::Center,
                        ..default()
                    },
                    ..default()
                },
                OnGameScreen,
            ))
            .with_children(|parent| {
                // First create a `NodeBundle` for centering what we want to display
                parent
                    .spawn(NodeBundle {
                        style: Style {
                            // This will display its children in a column, from top to bottom
                            flex_direction: FlexDirection::Column,
                            // `align_items` will align children on the cross axis. Here the main axis is
                            // vertical (column), so the cross axis is horizontal. This will center the
                            // children
                            align_items: AlignItems::Center,
                            ..default()
                        },
                        background_color: Color::BLACK.into(),
                        ..default()
                    })
                    .with_children(|parent| {
                        // Display two lines of text, the second one with the current settings
                        parent.spawn(
                            TextBundle::from_section(
                                "Will be back to the menu shortly...",
                                TextStyle {
                                    font_size: 80.0,
                                    color: TEXT_COLOR,
                                    ..default()
                                },
                            )
                            .with_style(Style {
                                margin: UiRect::all(Val::Px(50.0)),
                                ..default()
                            }),
                        );
                        parent.spawn(
                            TextBundle::from_sections([
                                TextSection::new(
                                    format!("quality: {:?}", *display_quality),
                                    TextStyle {
                                        font_size: 60.0,
                                        color: BLUE.into(),
                                        ..default()
                                    },
                                ),
                                TextSection::new(
                                    " - ",
                                    TextStyle {
                                        font_size: 60.0,
                                        color: TEXT_COLOR,
                                        ..default()
                                    },
                                ),
                                TextSection::new(
                                    format!("volume: {:?}", *volume),
                                    TextStyle {
                                        font_size: 60.0,
                                        color: LIME.into(),
                                        ..default()
                                    },
                                ),
                            ])
                            .with_style(Style {
                                margin: UiRect::all(Val::Px(50.0)),
                                ..default()
                            }),
                        );
                    });
            });
        // Spawn a 5 seconds timer to trigger going back to the menu
        commands.insert_resource(GameTimer(Timer::from_seconds(5.0, TimerMode::Once)));
    }

    // Tick the timer, and change state when finished
    fn game(
        time: Res<Time>,
        mut game_state: ResMut<NextState<GameState>>,
        mut timer: ResMut<GameTimer>,
    ) {
        if timer.tick(time.delta()).finished() {
            game_state.set(GameState::Menu);
        }
    }
}

mod menu {
    use bevy::{app::AppExit, color::palettes::css::CRIMSON, prelude::*};

    use super::{despawn_screen, DisplayQuality, GameState, Volume, TEXT_COLOR};

    // This plugin manages the menu, with 5 different screens:
    // - a main menu with "New Game", "Settings", "Quit"
    // - a settings menu with two submenus and a back button
    // - two settings screen with a setting that can be set and a back button
    pub fn menu_plugin(app: &mut App) {
        app
            // At start, the menu is not enabled. This will be changed in `menu_setup` when
            // entering the `GameState::Menu` state.
            // Current screen in the menu is handled by an independent state from `GameState`
            .init_state::<MenuState>()
            .add_systems(OnEnter(GameState::Menu), menu_setup)
            // Systems to handle the main menu screen
            .add_systems(OnEnter(MenuState::Main), main_menu_setup)
            .add_systems(OnExit(MenuState::Main), despawn_screen::<OnMainMenuScreen>)
            // Systems to handle the settings menu screen
            .add_systems(OnEnter(MenuState::Settings), settings_menu_setup)
            .add_systems(
                OnExit(MenuState::Settings),
                despawn_screen::<OnSettingsMenuScreen>,
            )
            // Systems to handle the display settings screen
            .add_systems(
                OnEnter(MenuState::SettingsDisplay),
                display_settings_menu_setup,
            )
            .add_systems(
                Update,
                (setting_button::<DisplayQuality>.run_if(in_state(MenuState::SettingsDisplay)),),
            )
            .add_systems(
                OnExit(MenuState::SettingsDisplay),
                despawn_screen::<OnDisplaySettingsMenuScreen>,
            )
            // Systems to handle the sound settings screen
            .add_systems(OnEnter(MenuState::SettingsSound), sound_settings_menu_setup)
            .add_systems(
                Update,
                setting_button::<Volume>.run_if(in_state(MenuState::SettingsSound)),
            )
            .add_systems(
                OnExit(MenuState::SettingsSound),
                despawn_screen::<OnSoundSettingsMenuScreen>,
            )
            // Common systems to all screens that handles buttons behavior
            .add_systems(
                Update,
                (menu_action, button_system).run_if(in_state(GameState::Menu)),
            );
    }
examples/ecs/generic_system.rs (line 42)
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_state::<AppState>()
        .add_systems(Startup, setup_system)
        .add_systems(
            Update,
            (
                print_text_system,
                transition_to_in_game_system.run_if(in_state(AppState::MainMenu)),
            ),
        )
        // Cleanup systems.
        // Pass in the types your system should operate on using the ::<T> (turbofish) syntax
        .add_systems(OnExit(AppState::MainMenu), cleanup_system::<MenuClose>)
        .add_systems(OnExit(AppState::InGame), cleanup_system::<LevelUnload>)
        .run();
}

fn ambiguous_with<M>( self, set: impl IntoSystemSet<M>, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Suppress warnings and errors that would result from these systems having ambiguities (conflicting access but indeterminate order) with systems in set.

Examples found in repository?
examples/ecs/nondeterministic_system_order.rs (line 53)
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
fn main() {
    App::new()
        // We can modify the reporting strategy for system execution order ambiguities on a per-schedule basis.
        // You must do this for each schedule you want to inspect; child schedules executed within an inspected
        // schedule do not inherit this modification.
        .edit_schedule(Update, |schedule| {
            schedule.set_build_settings(ScheduleBuildSettings {
                ambiguity_detection: LogLevel::Warn,
                ..default()
            });
        })
        .init_resource::<A>()
        .init_resource::<B>()
        .add_systems(
            Update,
            (
                // This pair of systems has an ambiguous order,
                // as their data access conflicts, and there's no order between them.
                reads_a,
                writes_a,
                // This pair of systems has conflicting data access,
                // but it's resolved with an explicit ordering:
                // the .after relationship here means that we will always double after adding.
                adds_one_to_b,
                doubles_b.after(adds_one_to_b),
                // This system isn't ambiguous with adds_one_to_b,
                // due to the transitive ordering created by our constraints:
                // if A is before B is before C, then A must be before C as well.
                reads_b.after(doubles_b),
                // This system will conflict with all of our writing systems
                // but we've silenced its ambiguity with adds_one_to_b.
                // This should only be done in the case of clear false positives:
                // leave a comment in your code justifying the decision!
                reads_a_and_b.ambiguous_with(adds_one_to_b),
            ),
        )
        // Be mindful, internal ambiguities are reported too!
        // If there are any ambiguities due solely to DefaultPlugins,
        // or between DefaultPlugins and any of your third party plugins,
        // please file a bug with the repo responsible!
        // Only *you* can prevent nondeterministic bugs due to greedy parallelism.
        .add_plugins(DefaultPlugins)
        .run();
}

fn ambiguous_with_all(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Suppress warnings and errors that would result from these systems having ambiguities (conflicting access but indeterminate order) with any other system.

fn chain(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Treat this collection as a sequence of systems.

Ordering constraints will be applied between the successive elements.

If the preceding node on a edge has deferred parameters, a apply_deferred will be inserted on the edge. If this behavior is not desired consider using chain_ignore_deferred instead.

Examples found in repository?
examples/gizmos/axes.rs (line 14)
10
11
12
13
14
15
16
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, (move_cubes, draw_axes).chain())
        .run();
}
More examples
Hide additional examples
examples/math/smooth_follow.rs (line 12)
8
9
10
11
12
13
14
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, (move_target, move_follower).chain())
        .run();
}
examples/camera/2d_top_down_camera.rs (line 30)
26
27
28
29
30
31
32
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, (setup_scene, setup_instructions, setup_camera))
        .add_systems(Update, (move_player, update_camera).chain())
        .run();
}
examples/transforms/align.rs (line 14)
9
10
11
12
13
14
15
16
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, (draw_ship_axes, draw_random_axes))
        .add_systems(Update, (handle_keypress, handle_mouse, rotate_ship).chain())
        .run();
}
examples/3d/clearcoat.rs (line 57)
50
51
52
53
54
55
56
57
58
59
pub fn main() {
    App::new()
        .init_resource::<LightMode>()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, animate_light)
        .add_systems(Update, animate_spheres)
        .add_systems(Update, (handle_input, update_help_text).chain())
        .run();
}
examples/transforms/transform.rs (line 35)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (
                move_cube,
                rotate_cube,
                scale_down_sphere_proportional_to_cube_travel_distance,
            )
                .chain(),
        )
        .run();
}

fn chain_ignore_deferred( self, ) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Treat this collection as a sequence of systems.

Ordering constraints will be applied between the successive elements.

Unlike chain this will not add apply_deferred on the edges.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

impl IntoSystemConfigs<()> for Box<dyn System<In = (), Out = ()>>

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0> IntoSystemConfigs<(SystemConfigTupleMarker, P0)> for (S0,)
where S0: IntoSystemConfigs<P0>,

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1)> for (S0, S1)
where S0: IntoSystemConfigs<P0>, S1: IntoSystemConfigs<P1>,

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2)> for (S0, S1, S2)
where S0: IntoSystemConfigs<P0>, S1: IntoSystemConfigs<P1>, S2: IntoSystemConfigs<P2>,

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3)> for (S0, S1, S2, S3)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4)> for (S0, S1, S2, S3, S4)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5)> for (S0, S1, S2, S3, S4, S5)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6)> for (S0, S1, S2, S3, S4, S5, S6)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7)> for (S0, S1, S2, S3, S4, S5, S6, S7)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12, P13, S13> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12, P13, S13, P14, S14> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12, P13, S13, P14, S14, P15, S15> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12, P13, S13, P14, S14, P15, S15, P16, S16> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12, P13, S13, P14, S14, P15, S15, P16, S16, P17, S17> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16, S17)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12, P13, S13, P14, S14, P15, S15, P16, S16, P17, S17, P18, S18> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16, S17, S18)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<P0, S0, P1, S1, P2, S2, P3, S3, P4, S4, P5, S5, P6, S6, P7, S7, P8, S8, P9, S9, P10, S10, P11, S11, P12, S12, P13, S13, P14, S14, P15, S15, P16, S16, P17, S17, P18, S18, P19, S19> IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19)> for (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19)

§

fn into_configs(self) -> NodeConfigs<Box<dyn System<In = (), Out = ()>>>

Implementors§

§

impl IntoSystemConfigs<()> for NodeConfigs<Box<dyn System<In = (), Out = ()>>>

§

impl<Marker, F> IntoSystemConfigs<Marker> for F
where F: IntoSystem<(), (), Marker>,