Skip to main content

Commands

Struct Commands 

Source
pub struct Commands<'w, 's> { /* private fields */ }
Expand description

A Command queue to perform structural changes to the World.

Since each command requires exclusive access to the World, all queued commands are automatically applied in sequence when the ApplyDeferred system runs (see ApplyDeferred documentation for more details).

Each command can be used to modify the World in arbitrary ways:

  • spawning or despawning entities
  • inserting components on new or existing entities
  • inserting resources
  • etc.

For a version of Commands that works in parallel contexts (such as within Query::par_iter) see ParallelCommands

§Usage

Add mut commands: Commands as a function argument to your system to get a copy of this struct that will be applied the next time a copy of ApplyDeferred runs. Commands are almost always used as a SystemParam.

fn my_system(mut commands: Commands) {
   // ...
}

§Implementing

Each built-in command is implemented as a separate method, e.g. Commands::spawn. In addition to the pre-defined command methods, you can add commands with any arbitrary behavior using Commands::queue, which accepts any type implementing Command.

Since closures and other functions implement this trait automatically, this allows one-shot, anonymous custom commands.

// NOTE: type inference fails here, so annotations are required on the closure.
commands.queue(|w: &mut World| {
    // Mutate the world however you want...
});

§Error handling

A Command can return a Result, which will be passed to an error handler if the Result is an error.

The fallback error handler panics. It can be configured via the FallbackErrorHandler resource.

Alternatively, you can customize the error handler for a specific command by calling Commands::queue_handled.

The error module provides some simple error handlers for convenience.

Implementations§

Source§

impl<'w, 's> Commands<'w, 's>

Source

pub fn new(queue: &'s mut CommandQueue, world: &'w World) -> Commands<'w, 's>

Returns a new Commands instance from a CommandQueue and a World.

Source

pub fn new_from_entities( queue: &'s mut CommandQueue, allocator: &'w EntityAllocator, entities: &'w Entities, ) -> Commands<'w, 's>

Returns a new Commands instance from a CommandQueue and an Entities reference.

Source

pub fn rebound_to<'q>(&self, queue: &'q mut CommandQueue) -> Commands<'w, 'q>

Returns a new Commands that writes commands to the provided CommandQueue instead of the one from self.

This is useful if you have a Commands that writes to one queue and you want one that writes to another.

Note that you’re responsible for ensuring the queue eventually writes its commands to the world. One way to do this is calling Commands::append on a Commands that writes to the world queue. Failure to write a queue may result in entities being allocated but never spawned, which means those entity IDs are never freed for reuse.

The original Commands isn’t mutated or borrowed after this returns, so you can keep using it.

Source

pub fn reborrow(&mut self) -> Commands<'w, '_>

Returns a Commands with a smaller lifetime.

This is useful if you have &mut Commands but need Commands.

§Example
fn my_system(mut commands: Commands) {
    // We do our initialization in a separate function,
    // which expects an owned `Commands`.
    do_initialization(commands.reborrow());

    // Since we only reborrowed the commands instead of moving them, we can still use them.
    commands.spawn_empty();
}
Source

pub fn append(&mut self, other: &mut CommandQueue)

Take all commands from other and append them to self, leaving other empty.

Examples found in repository?
examples/async_tasks/async_compute.rs (line 136)
128fn handle_tasks(
129    mut commands: Commands,
130    mut transform_tasks: Query<(Entity, &mut ComputeTransform)>,
131) {
132    for (entity, mut task) in &mut transform_tasks {
133        // Use `check_ready` to efficiently poll the task without blocking the main thread.
134        if let Some(mut commands_queue) = check_ready(&mut task.0) {
135            // Append the returned command queue to execute it later.
136            commands.append(&mut commands_queue);
137            // Task is complete, so remove the task component from the entity.
138            commands.entity(entity).remove::<ComputeTransform>();
139        }
140    }
141}
Source

pub fn spawn_empty(&mut self) -> EntityCommands<'_>

Spawns a new empty Entity and returns its corresponding EntityCommands.

§Example
#[derive(Component)]
struct Label(&'static str);
#[derive(Component)]
struct Strength(u32);
#[derive(Component)]
struct Agility(u32);

fn example_system(mut commands: Commands) {
    // Create a new empty entity.
    commands.spawn_empty();

    // Create another empty entity.
    commands.spawn_empty()
        // Add a new component bundle to the entity.
        .insert((Strength(1), Agility(2)))
        // Add a single component to the entity.
        .insert(Label("hello world"));
}
§See also
  • spawn to spawn an entity with components.
  • spawn_batch to spawn many entities with the same combination of components.
Examples found in repository?
examples/async_tasks/async_compute.rs (line 74)
66fn spawn_tasks(mut commands: Commands) {
67    let thread_pool = AsyncComputeTaskPool::get();
68    for x in 0..NUM_CUBES {
69        for y in 0..NUM_CUBES {
70            for z in 0..NUM_CUBES {
71                // Spawn new task on the AsyncComputeTaskPool; the task will be
72                // executed in the background, and the Task future returned by
73                // spawn() can be used to poll for the result
74                let entity = commands.spawn_empty().id();
75                let task = thread_pool.spawn(async move {
76                    let duration = Duration::from_secs_f32(rand::rng().random_range(0.05..5.0));
77
78                    // Pretend this is a time-intensive function. :)
79                    Delay::new(duration).await;
80
81                    // Such hard work, all done!
82                    let transform = Transform::from_xyz(x as f32, y as f32, z as f32);
83                    let mut command_queue = CommandQueue::default();
84
85                    // we use a raw command queue to pass a FnOnce(&mut World) back to be
86                    // applied in a deferred manner.
87                    command_queue.push(move |world: &mut World| {
88                        let (box_mesh_handle, box_material_handle) = {
89                            let mut system_state = SystemState::<(
90                                Res<BoxMeshHandle>,
91                                Res<BoxMaterialHandle>,
92                            )>::new(world);
93                            let (box_mesh_handle, box_material_handle) =
94                                system_state.get_mut(world).unwrap();
95
96                            (box_mesh_handle.clone(), box_material_handle.clone())
97                        };
98
99                        world
100                            .entity_mut(entity)
101                            // Add our new `Mesh3d` and `MeshMaterial3d` to our tagged entity
102                            .insert((
103                                Mesh3d(box_mesh_handle),
104                                MeshMaterial3d(box_material_handle),
105                                transform,
106                            ));
107                    });
108
109                    command_queue
110                });
111
112                // Add our new task as a component
113                commands.entity(entity).insert(ComputeTransform(task));
114            }
115        }
116    }
117}
More examples
Hide additional examples
examples/stress_tests/transform_hierarchy.rs (line 405)
354fn spawn_tree(
355    parent_map: &[usize],
356    commands: &mut Commands,
357    update_filter: &UpdateFilter,
358    root_transform: Transform,
359) -> InsertResult {
360    // total count (# of nodes + root)
361    let count = parent_map.len() + 1;
362
363    #[derive(Default, Clone, Copy)]
364    struct NodeInfo {
365        child_count: u32,
366        depth: u32,
367    }
368
369    // node index -> entity lookup list
370    let mut ents: Vec<Entity> = Vec::with_capacity(count);
371    let mut node_info: Vec<NodeInfo> = vec![default(); count];
372    for (i, &parent_idx) in parent_map.iter().enumerate() {
373        // assert spawn order (parent must be processed before child)
374        assert!(parent_idx <= i, "invalid spawn order");
375        node_info[parent_idx].child_count += 1;
376    }
377
378    // insert root
379    ents.push(commands.spawn(root_transform).id());
380
381    let mut result = InsertResult::default();
382    let mut rng = rand::rng();
383    // used to count through the number of children (used only for visual layout)
384    let mut child_idx: Vec<u16> = vec![0; count];
385
386    // insert children
387    for (current_idx, &parent_idx) in parent_map.iter().enumerate() {
388        let current_idx = current_idx + 1;
389
390        // separation factor to visually separate children (0..1)
391        let sep = child_idx[parent_idx] as f32 / node_info[parent_idx].child_count as f32;
392        child_idx[parent_idx] += 1;
393
394        // calculate and set depth
395        // this works because it's guaranteed that we have already iterated over the parent
396        let depth = node_info[parent_idx].depth + 1;
397        let info = &mut node_info[current_idx];
398        info.depth = depth;
399
400        // update max depth of tree
401        result.maximum_depth = result.maximum_depth.max(depth.try_into().unwrap());
402
403        // insert child
404        let child_entity = {
405            let mut cmd = commands.spawn_empty();
406
407            // check whether or not to update this node
408            let update = (rng.random::<f32>() <= update_filter.probability)
409                && (depth >= update_filter.min_depth && depth <= update_filter.max_depth);
410
411            if update {
412                cmd.insert(UpdateValue(sep));
413                result.active_nodes += 1;
414            }
415
416            let transform = {
417                let mut translation = Vec3::ZERO;
418                // use the same placement fn as the `update` system
419                // this way the entities won't be all at (0, 0, 0) when they don't have an `Update` component
420                set_translation(&mut translation, sep);
421                Transform::from_translation(translation)
422            };
423
424            // only insert the components necessary for the transform propagation
425            cmd.insert(transform);
426
427            cmd.id()
428        };
429
430        commands.entity(ents[parent_idx]).add_child(child_entity);
431
432        ents.push(child_entity);
433    }
434
435    result.inserted_nodes = ents.len();
436    result
437}
Source

pub fn spawn<T>(&mut self, bundle: T) -> EntityCommands<'_>
where T: Bundle,

Spawns a new Entity with the given components and returns the entity’s corresponding EntityCommands.

To spawn many entities with the same combination of components, spawn_batch can be used for better performance.

§Example
#[derive(Component)]
struct ComponentA(u32);
#[derive(Component)]
struct ComponentB(u32);

#[derive(Bundle)]
struct ExampleBundle {
    a: ComponentA,
    b: ComponentB,
}

fn example_system(mut commands: Commands) {
    // Create a new entity with a single component.
    commands.spawn(ComponentA(1));

    // Create a new entity with two components using a "tuple bundle".
    commands.spawn((ComponentA(2), ComponentB(1)));

    // Create a new entity with a component bundle.
    commands.spawn(ExampleBundle {
        a: ComponentA(3),
        b: ComponentB(2),
    });
}
§See also
  • spawn_empty to spawn an entity without any components.
  • spawn_batch to spawn many entities with the same combination of components.
Examples found in repository?
examples/showcase/game_menu.rs (line 48)
47fn setup(mut commands: Commands) {
48    commands.spawn(Camera2d);
49}
50
51mod splash {
52    use bevy::prelude::*;
53
54    use super::GameState;
55
56    // This plugin will display a splash screen with Bevy logo for 1 second before switching to the menu
57    pub fn splash_plugin(app: &mut App) {
58        // As this plugin is managing the splash screen, it will focus on the state `GameState::Splash`
59        app
60            // When entering the state, spawn everything needed for this screen
61            .add_systems(OnEnter(GameState::Splash), splash_setup)
62            // While in this state, run the `countdown` system
63            .add_systems(Update, countdown.run_if(in_state(GameState::Splash)));
64    }
65
66    // Tag component used to tag entities added on the splash screen
67    #[derive(Component)]
68    struct OnSplashScreen;
69
70    // Newtype to use a `Timer` for this screen as a resource
71    #[derive(Resource, Deref, DerefMut)]
72    struct SplashTimer(Timer);
73
74    fn splash_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
75        let icon = asset_server.load("branding/icon.png");
76        // Display the logo
77        commands.spawn((
78            // This entity will be despawned when exiting the state
79            DespawnOnExit(GameState::Splash),
80            Node {
81                align_items: AlignItems::Center,
82                justify_content: JustifyContent::Center,
83                width: percent(100),
84                height: percent(100),
85                ..default()
86            },
87            OnSplashScreen,
88            children![(
89                ImageNode::new(icon),
90                Node {
91                    // This will set the logo to be 200px wide, and auto adjust its height
92                    width: px(200),
93                    ..default()
94                },
95            )],
96        ));
97        // Insert the timer as a resource
98        commands.insert_resource(SplashTimer(Timer::from_seconds(1.0, TimerMode::Once)));
99    }
100
101    // Tick the timer, and change state when finished
102    fn countdown(
103        mut game_state: ResMut<NextState<GameState>>,
104        time: Res<Time>,
105        mut timer: ResMut<SplashTimer>,
106    ) {
107        if timer.tick(time.delta()).is_finished() {
108            game_state.set(GameState::Menu);
109        }
110    }
111}
112
113mod game {
114    use bevy::{
115        color::palettes::basic::{BLUE, LIME},
116        prelude::*,
117    };
118
119    use super::{DisplayQuality, GameState, Volume, TEXT_COLOR};
120
121    // This plugin will contain the game. In this case, it's just be a screen that will
122    // display the current settings for 5 seconds before returning to the menu
123    pub fn game_plugin(app: &mut App) {
124        app.add_systems(OnEnter(GameState::Game), game_setup)
125            .add_systems(Update, game.run_if(in_state(GameState::Game)));
126    }
127
128    // Tag component used to tag entities added on the game screen
129    #[derive(Component)]
130    struct OnGameScreen;
131
132    #[derive(Resource, Deref, DerefMut)]
133    struct GameTimer(Timer);
134
135    fn game_setup(
136        mut commands: Commands,
137        display_quality: Res<DisplayQuality>,
138        volume: Res<Volume>,
139    ) {
140        commands.spawn((
141            DespawnOnExit(GameState::Game),
142            Node {
143                width: percent(100),
144                height: percent(100),
145                // center children
146                align_items: AlignItems::Center,
147                justify_content: JustifyContent::Center,
148                ..default()
149            },
150            OnGameScreen,
151            children![(
152                Node {
153                    // This will display its children in a column, from top to bottom
154                    flex_direction: FlexDirection::Column,
155                    // `align_items` will align children on the cross axis. Here the main axis is
156                    // vertical (column), so the cross axis is horizontal. This will center the
157                    // children
158                    align_items: AlignItems::Center,
159                    ..default()
160                },
161                BackgroundColor(Color::BLACK),
162                children![
163                    (
164                        Text::new("Will be back to the menu shortly..."),
165                        TextFont {
166                            font_size: FontSize::Px(67.0),
167                            ..default()
168                        },
169                        TextColor(TEXT_COLOR),
170                        Node {
171                            margin: UiRect::all(px(50)),
172                            ..default()
173                        },
174                    ),
175                    (
176                        Text::default(),
177                        Node {
178                            margin: UiRect::all(px(50)),
179                            ..default()
180                        },
181                        children![
182                            (
183                                TextSpan(format!("quality: {:?}", *display_quality)),
184                                TextFont {
185                                    font_size: FontSize::Px(50.0),
186                                    ..default()
187                                },
188                                TextColor(BLUE.into()),
189                            ),
190                            (
191                                TextSpan::new(" - "),
192                                TextFont {
193                                    font_size: FontSize::Px(50.0),
194                                    ..default()
195                                },
196                                TextColor(TEXT_COLOR),
197                            ),
198                            (
199                                TextSpan(format!("volume: {:?}", *volume)),
200                                TextFont {
201                                    font_size: FontSize::Px(50.0),
202                                    ..default()
203                                },
204                                TextColor(LIME.into()),
205                            ),
206                        ]
207                    ),
208                ]
209            )],
210        ));
211        // Spawn a 5 seconds timer to trigger going back to the menu
212        commands.insert_resource(GameTimer(Timer::from_seconds(5.0, TimerMode::Once)));
213    }
214
215    // Tick the timer, and change state when finished
216    fn game(
217        time: Res<Time>,
218        mut game_state: ResMut<NextState<GameState>>,
219        mut timer: ResMut<GameTimer>,
220    ) {
221        if timer.tick(time.delta()).is_finished() {
222            game_state.set(GameState::Menu);
223        }
224    }
225}
226
227mod menu {
228    use bevy::{
229        app::AppExit,
230        color::palettes::css::CRIMSON,
231        ecs::component::Mutable,
232        ecs::spawn::{SpawnIter, SpawnWith},
233        prelude::*,
234    };
235
236    use super::{DisplayQuality, GameState, Setting, Volume, TEXT_COLOR};
237
238    // This plugin manages the menu, with 5 different screens:
239    // - a main menu with "New Game", "Settings", "Quit"
240    // - a settings menu with two submenus and a back button
241    // - two settings screen with a setting that can be set and a back button
242    pub fn menu_plugin(app: &mut App) {
243        app
244            // At start, the menu is not enabled. This will be changed in `menu_setup` when
245            // entering the `GameState::Menu` state.
246            // Current screen in the menu is handled by an independent state from `GameState`
247            .init_state::<MenuState>()
248            .add_systems(OnEnter(GameState::Menu), menu_setup)
249            // Systems to handle the main menu screen
250            .add_systems(OnEnter(MenuState::Main), main_menu_setup)
251            // Systems to handle the settings menu screen
252            .add_systems(OnEnter(MenuState::Settings), settings_menu_setup)
253            // Systems to handle the display settings screen
254            .add_systems(
255                OnEnter(MenuState::SettingsDisplay),
256                display_settings_menu_setup,
257            )
258            .add_systems(
259                Update,
260                (setting_button::<DisplayQuality>.run_if(in_state(MenuState::SettingsDisplay)),),
261            )
262            // Systems to handle the sound settings screen
263            .add_systems(OnEnter(MenuState::SettingsSound), sound_settings_menu_setup)
264            .add_systems(
265                Update,
266                setting_button::<Volume>.run_if(in_state(MenuState::SettingsSound)),
267            )
268            // Common systems to all screens that handles buttons behavior
269            .add_systems(
270                Update,
271                (menu_action, button_system).run_if(in_state(GameState::Menu)),
272            );
273    }
274
275    // State used for the current menu screen
276    #[derive(Clone, Copy, Default, Eq, PartialEq, Debug, Hash, States)]
277    enum MenuState {
278        Main,
279        Settings,
280        SettingsDisplay,
281        SettingsSound,
282        #[default]
283        Disabled,
284    }
285
286    // Tag component used to tag entities added on the main menu screen
287    #[derive(Component)]
288    struct OnMainMenuScreen;
289
290    // Tag component used to tag entities added on the settings menu screen
291    #[derive(Component)]
292    struct OnSettingsMenuScreen;
293
294    // Tag component used to tag entities added on the display settings menu screen
295    #[derive(Component)]
296    struct OnDisplaySettingsMenuScreen;
297
298    // Tag component used to tag entities added on the sound settings menu screen
299    #[derive(Component)]
300    struct OnSoundSettingsMenuScreen;
301
302    const NORMAL_BUTTON: Color = Color::srgb(0.15, 0.15, 0.15);
303    const HOVERED_BUTTON: Color = Color::srgb(0.25, 0.25, 0.25);
304    const HOVERED_PRESSED_BUTTON: Color = Color::srgb(0.25, 0.65, 0.25);
305    const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35);
306
307    // Tag component used to mark which setting is currently selected
308    #[derive(Component)]
309    struct SelectedOption;
310
311    // All actions that can be triggered from a button click
312    #[derive(Component)]
313    enum MenuButtonAction {
314        Play,
315        Settings,
316        SettingsDisplay,
317        SettingsSound,
318        BackToMainMenu,
319        BackToSettings,
320        Quit,
321    }
322
323    // This system handles changing all buttons color based on mouse interaction
324    fn button_system(
325        mut interaction_query: Query<
326            (&Interaction, &mut BackgroundColor, Option<&SelectedOption>),
327            (Changed<Interaction>, With<Button>),
328        >,
329    ) {
330        for (interaction, mut background_color, selected) in &mut interaction_query {
331            *background_color = match (*interaction, selected) {
332                (Interaction::Pressed, _) | (Interaction::None, Some(_)) => PRESSED_BUTTON.into(),
333                (Interaction::Hovered, Some(_)) => HOVERED_PRESSED_BUTTON.into(),
334                (Interaction::Hovered, None) => HOVERED_BUTTON.into(),
335                (Interaction::None, None) => NORMAL_BUTTON.into(),
336            }
337        }
338    }
339
340    // This system updates the settings when a new value for a setting is selected, and marks
341    // the button as the one currently selected
342    fn setting_button<T: Resource<Mutability = Mutable> + Component + PartialEq + Copy>(
343        interaction_query: Query<
344            (&Interaction, &Setting<T>, Entity),
345            (Changed<Interaction>, With<Button>),
346        >,
347        selected_query: Single<(Entity, &mut BackgroundColor), With<SelectedOption>>,
348        mut commands: Commands,
349        mut setting: ResMut<T>,
350    ) {
351        let (previous_button, mut previous_button_color) = selected_query.into_inner();
352        for (interaction, button_setting, entity) in &interaction_query {
353            if *interaction == Interaction::Pressed && *setting != button_setting.0 {
354                *previous_button_color = NORMAL_BUTTON.into();
355                commands.entity(previous_button).remove::<SelectedOption>();
356                commands.entity(entity).insert(SelectedOption);
357                *setting = button_setting.0;
358            }
359        }
360    }
361
362    fn menu_setup(mut menu_state: ResMut<NextState<MenuState>>) {
363        menu_state.set(MenuState::Main);
364    }
365
366    fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
367        // Common style for all buttons on the screen
368        let button_node = Node {
369            width: px(300),
370            height: px(65),
371            margin: UiRect::all(px(20)),
372            justify_content: JustifyContent::Center,
373            align_items: AlignItems::Center,
374            ..default()
375        };
376        let button_icon_node = Node {
377            width: px(30),
378            // This takes the icons out of the flexbox flow, to be positioned exactly
379            position_type: PositionType::Absolute,
380            // The icon will be close to the left border of the button
381            left: px(10),
382            ..default()
383        };
384        let button_text_font = TextFont {
385            font_size: FontSize::Px(33.0),
386            ..default()
387        };
388
389        let right_icon = asset_server.load("textures/Game Icons/right.png");
390        let wrench_icon = asset_server.load("textures/Game Icons/wrench.png");
391        let exit_icon = asset_server.load("textures/Game Icons/exitRight.png");
392
393        commands.spawn((
394            DespawnOnExit(MenuState::Main),
395            Node {
396                width: percent(100),
397                height: percent(100),
398                align_items: AlignItems::Center,
399                justify_content: JustifyContent::Center,
400                ..default()
401            },
402            OnMainMenuScreen,
403            children![(
404                Node {
405                    flex_direction: FlexDirection::Column,
406                    align_items: AlignItems::Center,
407                    ..default()
408                },
409                BackgroundColor(CRIMSON.into()),
410                children![
411                    // Display the game name
412                    (
413                        Text::new("Bevy Game Menu UI"),
414                        TextFont {
415                            font_size: FontSize::Px(67.0),
416                            ..default()
417                        },
418                        TextColor(TEXT_COLOR),
419                        Node {
420                            margin: UiRect::all(px(50)),
421                            ..default()
422                        },
423                    ),
424                    // Display three buttons for each action available from the main menu:
425                    // - new game
426                    // - settings
427                    // - quit
428                    (
429                        Button,
430                        button_node.clone(),
431                        BackgroundColor(NORMAL_BUTTON),
432                        MenuButtonAction::Play,
433                        children![
434                            (ImageNode::new(right_icon), button_icon_node.clone()),
435                            (
436                                Text::new("New Game"),
437                                button_text_font.clone(),
438                                TextColor(TEXT_COLOR),
439                            ),
440                        ]
441                    ),
442                    (
443                        Button,
444                        button_node.clone(),
445                        BackgroundColor(NORMAL_BUTTON),
446                        MenuButtonAction::Settings,
447                        children![
448                            (ImageNode::new(wrench_icon), button_icon_node.clone()),
449                            (
450                                Text::new("Settings"),
451                                button_text_font.clone(),
452                                TextColor(TEXT_COLOR),
453                            ),
454                        ]
455                    ),
456                    (
457                        Button,
458                        button_node,
459                        BackgroundColor(NORMAL_BUTTON),
460                        MenuButtonAction::Quit,
461                        children![
462                            (ImageNode::new(exit_icon), button_icon_node),
463                            (Text::new("Quit"), button_text_font, TextColor(TEXT_COLOR),),
464                        ]
465                    ),
466                ]
467            )],
468        ));
469    }
470
471    fn settings_menu_setup(mut commands: Commands) {
472        let button_node = Node {
473            width: px(200),
474            height: px(65),
475            margin: UiRect::all(px(20)),
476            justify_content: JustifyContent::Center,
477            align_items: AlignItems::Center,
478            ..default()
479        };
480
481        let button_text_style = (
482            TextFont {
483                font_size: FontSize::Px(33.0),
484                ..default()
485            },
486            TextColor(TEXT_COLOR),
487        );
488
489        commands.spawn((
490            DespawnOnExit(MenuState::Settings),
491            Node {
492                width: percent(100),
493                height: percent(100),
494                align_items: AlignItems::Center,
495                justify_content: JustifyContent::Center,
496                ..default()
497            },
498            OnSettingsMenuScreen,
499            children![(
500                Node {
501                    flex_direction: FlexDirection::Column,
502                    align_items: AlignItems::Center,
503                    ..default()
504                },
505                BackgroundColor(CRIMSON.into()),
506                Children::spawn(SpawnIter(
507                    [
508                        (MenuButtonAction::SettingsDisplay, "Display"),
509                        (MenuButtonAction::SettingsSound, "Sound"),
510                        (MenuButtonAction::BackToMainMenu, "Back"),
511                    ]
512                    .into_iter()
513                    .map(move |(action, text)| {
514                        (
515                            Button,
516                            button_node.clone(),
517                            BackgroundColor(NORMAL_BUTTON),
518                            action,
519                            children![(Text::new(text), button_text_style.clone())],
520                        )
521                    })
522                ))
523            )],
524        ));
525    }
526
527    fn display_settings_menu_setup(mut commands: Commands, display_quality: Res<DisplayQuality>) {
528        fn button_node() -> Node {
529            Node {
530                width: px(200),
531                height: px(65),
532                margin: UiRect::all(px(20)),
533                justify_content: JustifyContent::Center,
534                align_items: AlignItems::Center,
535                ..default()
536            }
537        }
538        fn button_text_style() -> impl Bundle {
539            (
540                TextFont {
541                    font_size: FontSize::Px(33.0),
542                    ..default()
543                },
544                TextColor(TEXT_COLOR),
545            )
546        }
547
548        let display_quality = *display_quality;
549        commands.spawn((
550            DespawnOnExit(MenuState::SettingsDisplay),
551            Node {
552                width: percent(100),
553                height: percent(100),
554                align_items: AlignItems::Center,
555                justify_content: JustifyContent::Center,
556                ..default()
557            },
558            OnDisplaySettingsMenuScreen,
559            children![(
560                Node {
561                    flex_direction: FlexDirection::Column,
562                    align_items: AlignItems::Center,
563                    ..default()
564                },
565                BackgroundColor(CRIMSON.into()),
566                children![
567                    // Create a new `Node`, this time not setting its `flex_direction`. It will
568                    // use the default value, `FlexDirection::Row`, from left to right.
569                    (
570                        Node {
571                            align_items: AlignItems::Center,
572                            ..default()
573                        },
574                        BackgroundColor(CRIMSON.into()),
575                        Children::spawn((
576                            // Display a label for the current setting
577                            Spawn((Text::new("Display Quality"), button_text_style())),
578                            SpawnWith(move |parent: &mut ChildSpawner| {
579                                for quality_setting in [
580                                    DisplayQuality::Low,
581                                    DisplayQuality::Medium,
582                                    DisplayQuality::High,
583                                ] {
584                                    let mut entity = parent.spawn((
585                                        Button,
586                                        Node {
587                                            width: px(150),
588                                            height: px(65),
589                                            ..button_node()
590                                        },
591                                        BackgroundColor(NORMAL_BUTTON),
592                                        Setting(quality_setting),
593                                        children![(
594                                            Text::new(format!("{quality_setting:?}")),
595                                            button_text_style(),
596                                        )],
597                                    ));
598                                    if display_quality == quality_setting {
599                                        entity.insert(SelectedOption);
600                                    }
601                                }
602                            })
603                        ))
604                    ),
605                    // Display the back button to return to the settings screen
606                    (
607                        Button,
608                        button_node(),
609                        BackgroundColor(NORMAL_BUTTON),
610                        MenuButtonAction::BackToSettings,
611                        children![(Text::new("Back"), button_text_style())]
612                    )
613                ]
614            )],
615        ));
616    }
617
618    fn sound_settings_menu_setup(mut commands: Commands, volume: Res<Volume>) {
619        let button_node = Node {
620            width: px(200),
621            height: px(65),
622            margin: UiRect::all(px(20)),
623            justify_content: JustifyContent::Center,
624            align_items: AlignItems::Center,
625            ..default()
626        };
627        let button_text_style = (
628            TextFont {
629                font_size: FontSize::Px(33.0),
630                ..default()
631            },
632            TextColor(TEXT_COLOR),
633        );
634
635        let volume = *volume;
636        let button_node_clone = button_node.clone();
637        commands.spawn((
638            DespawnOnExit(MenuState::SettingsSound),
639            Node {
640                width: percent(100),
641                height: percent(100),
642                align_items: AlignItems::Center,
643                justify_content: JustifyContent::Center,
644                ..default()
645            },
646            OnSoundSettingsMenuScreen,
647            children![(
648                Node {
649                    flex_direction: FlexDirection::Column,
650                    align_items: AlignItems::Center,
651                    ..default()
652                },
653                BackgroundColor(CRIMSON.into()),
654                children![
655                    (
656                        Node {
657                            align_items: AlignItems::Center,
658                            ..default()
659                        },
660                        BackgroundColor(CRIMSON.into()),
661                        Children::spawn((
662                            Spawn((Text::new("Volume"), button_text_style.clone())),
663                            SpawnWith(move |parent: &mut ChildSpawner| {
664                                for volume_setting in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] {
665                                    let mut entity = parent.spawn((
666                                        Button,
667                                        Node {
668                                            width: px(30),
669                                            height: px(65),
670                                            ..button_node_clone.clone()
671                                        },
672                                        BackgroundColor(NORMAL_BUTTON),
673                                        Setting(Volume(volume_setting)),
674                                    ));
675                                    if volume == Volume(volume_setting) {
676                                        entity.insert(SelectedOption);
677                                    }
678                                }
679                            })
680                        ))
681                    ),
682                    (
683                        Button,
684                        button_node,
685                        BackgroundColor(NORMAL_BUTTON),
686                        MenuButtonAction::BackToSettings,
687                        children![(Text::new("Back"), button_text_style)]
688                    )
689                ]
690            )],
691        ));
692    }
More examples
Hide additional examples
examples/state/custom_transitions.rs (line 222)
221fn setup(mut commands: Commands) {
222    commands.spawn(Camera2d);
223}
224
225fn setup_game(mut commands: Commands, asset_server: Res<AssetServer>) {
226    commands.spawn(Sprite::from_image(asset_server.load("branding/icon.png")));
227    info!("Setup game");
228}
229
230fn teardown_game(mut commands: Commands, player: Single<Entity, With<Sprite>>) {
231    commands.entity(*player).despawn();
232    info!("Teardown game");
233}
234
235#[derive(Resource)]
236struct MenuData {
237    pub button_entity: Entity,
238}
239
240const NORMAL_BUTTON: Color = Color::srgb(0.15, 0.15, 0.15);
241const HOVERED_BUTTON: Color = Color::srgb(0.25, 0.25, 0.25);
242const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35);
243
244fn setup_menu(mut commands: Commands) {
245    let button_entity = commands
246        .spawn((
247            Node {
248                // center button
249                width: percent(100),
250                height: percent(100),
251                justify_content: JustifyContent::Center,
252                align_items: AlignItems::Center,
253                ..default()
254            },
255            children![(
256                Button,
257                Node {
258                    width: px(150),
259                    height: px(65),
260                    // horizontally center child text
261                    justify_content: JustifyContent::Center,
262                    // vertically center child text
263                    align_items: AlignItems::Center,
264                    ..default()
265                },
266                BackgroundColor(NORMAL_BUTTON),
267                children![(
268                    Text::new("Play"),
269                    TextFont {
270                        font_size: FontSize::Px(33.0),
271                        ..default()
272                    },
273                    TextColor(Color::srgb(0.9, 0.9, 0.9)),
274                )]
275            )],
276        ))
277        .id();
278    commands.insert_resource(MenuData { button_entity });
279}
examples/state/states.rs (line 54)
53fn setup(mut commands: Commands) {
54    commands.spawn(Camera2d);
55}
56
57fn setup_menu(mut commands: Commands) {
58    let button_entity = commands
59        .spawn((
60            Node {
61                // center button
62                width: percent(100),
63                height: percent(100),
64                justify_content: JustifyContent::Center,
65                align_items: AlignItems::Center,
66                ..default()
67            },
68            children![(
69                Button,
70                Node {
71                    width: px(150),
72                    height: px(65),
73                    // horizontally center child text
74                    justify_content: JustifyContent::Center,
75                    // vertically center child text
76                    align_items: AlignItems::Center,
77                    ..default()
78                },
79                BackgroundColor(NORMAL_BUTTON),
80                children![(
81                    Text::new("Play"),
82                    TextFont {
83                        font_size: FontSize::Px(33.0),
84                        ..default()
85                    },
86                    TextColor(Color::srgb(0.9, 0.9, 0.9)),
87                )],
88            )],
89        ))
90        .id();
91    commands.insert_resource(MenuData { button_entity });
92}
93
94fn menu(
95    mut next_state: ResMut<NextState<AppState>>,
96    mut interaction_query: Query<
97        (&Interaction, &mut BackgroundColor),
98        (Changed<Interaction>, With<Button>),
99    >,
100) {
101    for (interaction, mut color) in &mut interaction_query {
102        match *interaction {
103            Interaction::Pressed => {
104                *color = PRESSED_BUTTON.into();
105                next_state.set(AppState::InGame);
106            }
107            Interaction::Hovered => {
108                *color = HOVERED_BUTTON.into();
109            }
110            Interaction::None => {
111                *color = NORMAL_BUTTON.into();
112            }
113        }
114    }
115}
116
117fn cleanup_menu(mut commands: Commands, menu_data: Res<MenuData>) {
118    commands.entity(menu_data.button_entity).despawn();
119}
120
121fn setup_game(mut commands: Commands, asset_server: Res<AssetServer>) {
122    commands.spawn(Sprite::from_image(asset_server.load("branding/icon.png")));
123}
examples/window/clear_color.rs (line 17)
16fn setup(mut commands: Commands) {
17    commands.spawn(Camera2d);
18}
examples/2d/sprite_scale.rs (line 14)
13fn setup_camera(mut commands: Commands) {
14    commands.spawn(Camera2d);
15}
16
17fn setup_sprites(mut commands: Commands, asset_server: Res<AssetServer>) {
18    let square = asset_server.load("textures/slice_square_2.png");
19    let banner = asset_server.load("branding/banner.png");
20
21    let rects = [
22        Rect {
23            size: Vec2::new(100., 225.),
24            text: "Stretched".to_string(),
25            transform: Transform::from_translation(Vec3::new(-570., 230., 0.)),
26            texture: square.clone(),
27            image_mode: SpriteImageMode::Auto,
28        },
29        Rect {
30            size: Vec2::new(100., 225.),
31            text: "Fill Center".to_string(),
32            transform: Transform::from_translation(Vec3::new(-450., 230., 0.)),
33            texture: square.clone(),
34            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillCenter),
35        },
36        Rect {
37            size: Vec2::new(100., 225.),
38            text: "Fill Start".to_string(),
39            transform: Transform::from_translation(Vec3::new(-330., 230., 0.)),
40            texture: square.clone(),
41            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillStart),
42        },
43        Rect {
44            size: Vec2::new(100., 225.),
45            text: "Fill End".to_string(),
46            transform: Transform::from_translation(Vec3::new(-210., 230., 0.)),
47            texture: square.clone(),
48            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillEnd),
49        },
50        Rect {
51            size: Vec2::new(300., 100.),
52            text: "Fill Start Horizontal".to_string(),
53            transform: Transform::from_translation(Vec3::new(10., 290., 0.)),
54            texture: square.clone(),
55            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillStart),
56        },
57        Rect {
58            size: Vec2::new(300., 100.),
59            text: "Fill End Horizontal".to_string(),
60            transform: Transform::from_translation(Vec3::new(10., 155., 0.)),
61            texture: square.clone(),
62            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillEnd),
63        },
64        Rect {
65            size: Vec2::new(200., 200.),
66            text: "Fill Center".to_string(),
67            transform: Transform::from_translation(Vec3::new(280., 230., 0.)),
68            texture: banner.clone(),
69            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillCenter),
70        },
71        Rect {
72            size: Vec2::new(200., 100.),
73            text: "Fill Center".to_string(),
74            transform: Transform::from_translation(Vec3::new(500., 230., 0.)),
75            texture: square.clone(),
76            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillCenter),
77        },
78        Rect {
79            size: Vec2::new(100., 100.),
80            text: "Stretched".to_string(),
81            transform: Transform::from_translation(Vec3::new(-570., -40., 0.)),
82            texture: banner.clone(),
83            image_mode: SpriteImageMode::Auto,
84        },
85        Rect {
86            size: Vec2::new(200., 200.),
87            text: "Fit Center".to_string(),
88            transform: Transform::from_translation(Vec3::new(-400., -40., 0.)),
89            texture: banner.clone(),
90            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FitCenter),
91        },
92        Rect {
93            size: Vec2::new(200., 200.),
94            text: "Fit Start".to_string(),
95            transform: Transform::from_translation(Vec3::new(-180., -40., 0.)),
96            texture: banner.clone(),
97            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FitStart),
98        },
99        Rect {
100            size: Vec2::new(200., 200.),
101            text: "Fit End".to_string(),
102            transform: Transform::from_translation(Vec3::new(40., -40., 0.)),
103            texture: banner.clone(),
104            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FitEnd),
105        },
106        Rect {
107            size: Vec2::new(100., 200.),
108            text: "Fit Center".to_string(),
109            transform: Transform::from_translation(Vec3::new(210., -40., 0.)),
110            texture: banner.clone(),
111            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FitCenter),
112        },
113    ];
114
115    for rect in rects {
116        commands.spawn((
117            Sprite {
118                image: rect.texture,
119                custom_size: Some(rect.size),
120                image_mode: rect.image_mode,
121                ..default()
122            },
123            rect.transform,
124            children![(
125                Text2d::new(rect.text),
126                TextLayout::justify(Justify::Center),
127                TextFont::from_font_size(15.),
128                Transform::from_xyz(0., -0.5 * rect.size.y - 10., 0.),
129                bevy::sprite::Anchor::TOP_CENTER,
130            )],
131        ));
132    }
133}
134
135fn setup_texture_atlas(
136    mut commands: Commands,
137    asset_server: Res<AssetServer>,
138    mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
139) {
140    let gabe = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
141    let animation_indices_gabe = AnimationIndices { first: 0, last: 6 };
142    let gabe_atlas = TextureAtlas {
143        layout: texture_atlas_layouts.add(TextureAtlasLayout::from_grid(
144            UVec2::splat(24),
145            7,
146            1,
147            None,
148            None,
149        )),
150        index: animation_indices_gabe.first,
151    };
152
153    let sprite_sheets = [
154        SpriteSheet {
155            size: Vec2::new(120., 50.),
156            text: "Stretched".to_string(),
157            transform: Transform::from_translation(Vec3::new(-570., -200., 0.)),
158            texture: gabe.clone(),
159            image_mode: SpriteImageMode::Auto,
160            atlas: gabe_atlas.clone(),
161            indices: animation_indices_gabe.clone(),
162            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
163        },
164        SpriteSheet {
165            size: Vec2::new(120., 50.),
166            text: "Fill Center".to_string(),
167            transform: Transform::from_translation(Vec3::new(-570., -300., 0.)),
168            texture: gabe.clone(),
169            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillCenter),
170            atlas: gabe_atlas.clone(),
171            indices: animation_indices_gabe.clone(),
172            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
173        },
174        SpriteSheet {
175            size: Vec2::new(120., 50.),
176            text: "Fill Start".to_string(),
177            transform: Transform::from_translation(Vec3::new(-430., -200., 0.)),
178            texture: gabe.clone(),
179            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillStart),
180            atlas: gabe_atlas.clone(),
181            indices: animation_indices_gabe.clone(),
182            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
183        },
184        SpriteSheet {
185            size: Vec2::new(120., 50.),
186            text: "Fill End".to_string(),
187            transform: Transform::from_translation(Vec3::new(-430., -300., 0.)),
188            texture: gabe.clone(),
189            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillEnd),
190            atlas: gabe_atlas.clone(),
191            indices: animation_indices_gabe.clone(),
192            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
193        },
194        SpriteSheet {
195            size: Vec2::new(50., 120.),
196            text: "Fill Center".to_string(),
197            transform: Transform::from_translation(Vec3::new(-300., -250., 0.)),
198            texture: gabe.clone(),
199            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillCenter),
200            atlas: gabe_atlas.clone(),
201            indices: animation_indices_gabe.clone(),
202            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
203        },
204        SpriteSheet {
205            size: Vec2::new(50., 120.),
206            text: "Fill Start".to_string(),
207            transform: Transform::from_translation(Vec3::new(-190., -250., 0.)),
208            texture: gabe.clone(),
209            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillStart),
210            atlas: gabe_atlas.clone(),
211            indices: animation_indices_gabe.clone(),
212            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
213        },
214        SpriteSheet {
215            size: Vec2::new(50., 120.),
216            text: "Fill End".to_string(),
217            transform: Transform::from_translation(Vec3::new(-90., -250., 0.)),
218            texture: gabe.clone(),
219            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FillEnd),
220            atlas: gabe_atlas.clone(),
221            indices: animation_indices_gabe.clone(),
222            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
223        },
224        SpriteSheet {
225            size: Vec2::new(120., 50.),
226            text: "Fit Center".to_string(),
227            transform: Transform::from_translation(Vec3::new(20., -200., 0.)),
228            texture: gabe.clone(),
229            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FitCenter),
230            atlas: gabe_atlas.clone(),
231            indices: animation_indices_gabe.clone(),
232            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
233        },
234        SpriteSheet {
235            size: Vec2::new(120., 50.),
236            text: "Fit Start".to_string(),
237            transform: Transform::from_translation(Vec3::new(20., -300., 0.)),
238            texture: gabe.clone(),
239            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FitStart),
240            atlas: gabe_atlas.clone(),
241            indices: animation_indices_gabe.clone(),
242            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
243        },
244        SpriteSheet {
245            size: Vec2::new(120., 50.),
246            text: "Fit End".to_string(),
247            transform: Transform::from_translation(Vec3::new(160., -200., 0.)),
248            texture: gabe.clone(),
249            image_mode: SpriteImageMode::Scale(SpriteScalingMode::FitEnd),
250            atlas: gabe_atlas.clone(),
251            indices: animation_indices_gabe.clone(),
252            timer: AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
253        },
254    ];
255
256    for sprite_sheet in sprite_sheets {
257        commands.spawn((
258            Sprite {
259                image_mode: sprite_sheet.image_mode,
260                custom_size: Some(sprite_sheet.size),
261                ..Sprite::from_atlas_image(sprite_sheet.texture.clone(), sprite_sheet.atlas.clone())
262            },
263            sprite_sheet.indices,
264            sprite_sheet.timer,
265            sprite_sheet.transform,
266            children![(
267                Text2d::new(sprite_sheet.text),
268                TextLayout::justify(Justify::Center),
269                TextFont::from_font_size(15.),
270                Transform::from_xyz(0., -0.5 * sprite_sheet.size.y - 10., 0.),
271                bevy::sprite::Anchor::TOP_CENTER,
272            )],
273        ));
274    }
275}
examples/gizmos/anchored_text_gizmos.rs (line 18)
17fn setup_camera(mut commands: Commands) {
18    commands.spawn(Camera2d);
19}
Source

pub fn entity(&mut self, entity: Entity) -> EntityCommands<'_>

Returns the EntityCommands for the given Entity.

This method does not guarantee that commands queued by the returned EntityCommands will be successful, since the entity could be despawned before they are executed.

§Example
#[derive(Resource)]
struct PlayerEntity {
    entity: Entity
}

#[derive(Component)]
struct Label(&'static str);

fn example_system(mut commands: Commands, player: Res<PlayerEntity>) {
    // Get the entity and add a component.
    commands.entity(player.entity).insert(Label("hello world"));
}
§See also
Examples found in repository?
examples/state/custom_transitions.rs (line 166)
165fn cleanup_menu(mut commands: Commands, menu_data: Res<MenuData>) {
166    commands.entity(menu_data.button_entity).despawn();
167}
168
169const SPEED: f32 = 100.0;
170fn movement(
171    time: Res<Time>,
172    input: Res<ButtonInput<KeyCode>>,
173    mut query: Query<&mut Transform, With<Sprite>>,
174) {
175    for mut transform in &mut query {
176        let mut direction = Vec3::ZERO;
177        if input.pressed(KeyCode::ArrowLeft) {
178            direction.x -= 1.0;
179        }
180        if input.pressed(KeyCode::ArrowRight) {
181            direction.x += 1.0;
182        }
183        if input.pressed(KeyCode::ArrowUp) {
184            direction.y += 1.0;
185        }
186        if input.pressed(KeyCode::ArrowDown) {
187            direction.y -= 1.0;
188        }
189
190        if direction != Vec3::ZERO {
191            transform.translation += direction.normalize() * SPEED * time.delta_secs();
192        }
193    }
194}
195
196fn change_color(time: Res<Time>, mut query: Query<&mut Sprite>) {
197    for mut sprite in &mut query {
198        let new_color = LinearRgba {
199            blue: ops::sin(time.elapsed_secs() * 0.5) + 2.0,
200            ..LinearRgba::from(sprite.color)
201        };
202
203        sprite.color = new_color.into();
204    }
205}
206
207// We can restart the game by pressing "R".
208// This will trigger an [`AppState::InGame`] -> [`AppState::InGame`]
209// transition, which will run our custom schedules.
210fn trigger_game_restart(
211    input: Res<ButtonInput<KeyCode>>,
212    mut next_state: ResMut<NextState<AppState>>,
213) {
214    if input.just_pressed(KeyCode::KeyR) {
215        // Although we are already in this state setting it again will generate an identity transition.
216        // While default schedules ignore those kinds of transitions, our custom schedules will react to them.
217        next_state.set(AppState::InGame);
218    }
219}
220
221fn setup(mut commands: Commands) {
222    commands.spawn(Camera2d);
223}
224
225fn setup_game(mut commands: Commands, asset_server: Res<AssetServer>) {
226    commands.spawn(Sprite::from_image(asset_server.load("branding/icon.png")));
227    info!("Setup game");
228}
229
230fn teardown_game(mut commands: Commands, player: Single<Entity, With<Sprite>>) {
231    commands.entity(*player).despawn();
232    info!("Teardown game");
233}
More examples
Hide additional examples
examples/state/states.rs (line 118)
117fn cleanup_menu(mut commands: Commands, menu_data: Res<MenuData>) {
118    commands.entity(menu_data.button_entity).despawn();
119}
examples/state/sub_states.rs (line 87)
86fn cleanup_menu(mut commands: Commands, menu_data: Res<MenuData>) {
87    commands.entity(menu_data.button_entity).despawn();
88}
examples/remote/server.rs (line 86)
85fn remove(mut commands: Commands, cube_entity: Single<Entity, With<Cube>>) {
86    commands.entity(*cube_entity).remove::<Cube>();
87}
examples/state/computed_states.rs (line 406)
405    pub fn cleanup_menu(mut commands: Commands, menu_data: Res<MenuData>) {
406        commands.entity(menu_data.root_entity).despawn();
407    }
examples/stress_tests/many_buttons.rs (line 322)
321fn despawn_ui(mut commands: Commands, root_node: Single<Entity, (With<Node>, Without<ChildOf>)>) {
322    commands.entity(*root_node).despawn();
323}
Source

pub fn get_entity( &mut self, entity: Entity, ) -> Result<EntityCommands<'_>, InvalidEntityError>

Returns the EntityCommands for the requested Entity if it is valid. This method does not guarantee that commands queued by the returned EntityCommands will be successful, since the entity could be despawned before they are executed. This also does not error when the entity has not been spawned. For that behavior, see get_spawned_entity, which should be preferred for accessing entities you expect to already be spawned, like those found from a query. For details on entity spawning vs validity, see entity module docs.

§Errors

Returns InvalidEntityError if the requested entity does not exist.

§Example
#[derive(Resource)]
struct PlayerEntity {
    entity: Entity
}

#[derive(Component)]
struct Label(&'static str);

fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {
    // Get the entity if it still exists and store the `EntityCommands`.
    // If it doesn't exist, the `?` operator will propagate the returned error
    // to the system, and the system will pass it to an error handler.
    let mut entity_commands = commands.get_entity(player.entity)?;

    // Add a component to the entity.
    entity_commands.insert(Label("hello world"));

    // Return from the system successfully.
    Ok(())
}
§See also
  • entity for the infallible version.
Examples found in repository?
examples/ecs/observers.rs (line 165)
163fn explode_mine(explode: On<Explode>, query: Query<&Mine>, mut commands: Commands) {
164    // Explode is an EntityEvent. `explode.entity` is the entity that Explode was triggered for.
165    let Ok(mut entity) = commands.get_entity(explode.entity) else {
166        return;
167    };
168    info!("Boom! {} exploded.", explode.entity);
169    entity.despawn();
170    let mine = query.get(explode.entity).unwrap();
171    // Trigger another explosion cascade.
172    commands.trigger(ExplodeMines {
173        pos: mine.pos,
174        radius: mine.size,
175    });
176}
Source

pub fn get_spawned_entity( &mut self, entity: Entity, ) -> Result<EntityCommands<'_>, EntityNotSpawnedError>

Returns the EntityCommands for the requested Entity if it spawned in the world now. Note that for entities that have not been spawned yet, like ones from spawn, this will error. If that is not desired, try get_entity. This should be used over get_entity when you expect the entity to already be spawned in the world. If the entity is valid but not yet spawned, this will error that information, where get_entity would succeed, leading to potentially surprising results. For details on entity spawning vs validity, see entity module docs.

This method does not guarantee that commands queued by the returned EntityCommands will be successful, since the entity could be despawned before they are executed.

§Errors

Returns EntityNotSpawnedError if the requested entity does not exist.

§Example
#[derive(Resource)]
struct PlayerEntity {
    entity: Entity
}

#[derive(Component)]
struct Label(&'static str);

fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {
    // Get the entity if it still exists and store the `EntityCommands`.
    // If it doesn't exist, the `?` operator will propagate the returned error
    // to the system, and the system will pass it to an error handler.
    let mut entity_commands = commands.get_spawned_entity(player.entity)?;

    // Add a component to the entity.
    entity_commands.insert(Label("hello world"));

    // Return from the system successfully.
    Ok(())
}
§See also
  • entity for the infallible version.
Source

pub fn spawn_batch<I>(&mut self, batch: I)

Spawns multiple entities with the same combination of components, based on a batch of Bundles.

A batch can be any type that implements IntoIterator and contains bundles, such as a Vec<Bundle> or an array [Bundle; N].

This method is equivalent to iterating the batch and calling spawn for each bundle, but is faster by pre-allocating memory and having exclusive World access.

§Example
use bevy_ecs::prelude::*;

#[derive(Component)]
struct Score(u32);

fn example_system(mut commands: Commands) {
    commands.spawn_batch([
        (Name::new("Alice"), Score(0)),
        (Name::new("Bob"), Score(0)),
    ]);
}
§See also
  • spawn to spawn an entity with components.
  • spawn_empty to spawn an entity without components.
Examples found in repository?
examples/ecs/contiguous_query.rs (lines 59-66)
57fn setup(mut commands: Commands) {
58    let mut i = 0;
59    commands.spawn_batch(std::iter::from_fn(move || {
60        i += 1;
61        if i == 10_000 {
62            None
63        } else {
64            Some((Health(i as f32 * 5.0), HealthDecay(0.9)))
65        }
66    }));
67}
More examples
Hide additional examples
examples/ecs/ecs_guide.rs (lines 193-208)
183fn startup_system(mut commands: Commands, mut game_state: ResMut<GameState>) {
184    // Create our game rules resource
185    commands.insert_resource(GameRules {
186        max_rounds: 10,
187        winning_score: 4,
188        max_players: 4,
189    });
190
191    // Add some players to our world. Players start with a score of 0 ... we want our game to be
192    // fair!
193    commands.spawn_batch(vec![
194        (
195            Player {
196                name: "Alice".to_string(),
197            },
198            Score { value: 0 },
199            PlayerStreak::None,
200        ),
201        (
202            Player {
203                name: "Bob".to_string(),
204            },
205            Score { value: 0 },
206            PlayerStreak::None,
207        ),
208    ]);
209
210    // set the total players to "2"
211    game_state.total_players = 2;
212}
examples/3d/order_independent_transparency.rs (line 345)
317fn spawn_auto_instancing_test(
318    commands: &mut Commands,
319    meshes: &mut Assets<Mesh>,
320    materials: &mut Assets<StandardMaterial>,
321    asset_server: Res<AssetServer>,
322) {
323    let render_layers = RenderLayers::layer(1);
324
325    let cube = meshes.add(Cuboid::new(1.0, 1.0, 1.0));
326    let material_handle = materials.add(StandardMaterial {
327        alpha_mode: AlphaMode::Blend,
328        base_color_texture: Some(asset_server.load("textures/slice_square.png")),
329        ..Default::default()
330    });
331    let mut bundles = Vec::with_capacity(3 * 3 * 3);
332
333    for z in -1..=1 {
334        for y in -1..=1 {
335            for x in -1..=1 {
336                bundles.push((
337                    Mesh3d(cube.clone()),
338                    MeshMaterial3d(material_handle.clone()),
339                    Transform::from_xyz(x as f32 * 2.0, y as f32 * 2.0, z as f32 * 2.0),
340                    render_layers.clone(),
341                ));
342            }
343        }
344    }
345    commands.spawn_batch(bundles);
346}
examples/stress_tests/many_sprites.rs (line 99)
54fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<ColorTint>) {
55    warn!(include_str!("warning_string.txt"));
56
57    let mut rng = rand::rng();
58
59    let tile_size = Vec2::splat(64.0);
60    let map_size = Vec2::splat(320.0);
61
62    let half_x = (map_size.x / 2.0) as i32;
63    let half_y = (map_size.y / 2.0) as i32;
64
65    let sprite_handle = assets.load("branding/icon.png");
66
67    // Spawns the camera
68
69    commands.spawn(Camera2d);
70
71    // Builds and spawns the sprites
72    let mut sprites = vec![];
73    for y in -half_y..half_y {
74        for x in -half_x..half_x {
75            let position = Vec2::new(x as f32, y as f32);
76            let translation = (position * tile_size).extend(rng.random::<f32>());
77            let rotation = Quat::from_rotation_z(rng.random::<f32>());
78            let scale = Vec3::splat(rng.random::<f32>() * 2.0);
79
80            sprites.push((
81                Sprite {
82                    image: sprite_handle.clone(),
83                    custom_size: Some(tile_size),
84                    color: if color_tint.0 {
85                        COLORS[rng.random_range(0..3)]
86                    } else {
87                        Color::WHITE
88                    },
89                    ..default()
90                },
91                Transform {
92                    translation,
93                    rotation,
94                    scale,
95                },
96            ));
97        }
98    }
99    commands.spawn_batch(sprites);
100}
examples/stress_tests/many_sprite_meshes.rs (line 101)
56fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<ColorTint>) {
57    warn!(include_str!("warning_string.txt"));
58
59    let mut rng = rand::rng();
60
61    let tile_size = Vec2::splat(64.0);
62    let map_size = Vec2::splat(320.0);
63
64    let half_x = (map_size.x / 2.0) as i32;
65    let half_y = (map_size.y / 2.0) as i32;
66
67    let sprite_handle = assets.load("branding/icon.png");
68
69    // Spawns the camera
70
71    commands.spawn(Camera2d);
72
73    // Builds and spawns the sprites
74    let mut sprites = vec![];
75    for y in -half_y..half_y {
76        for x in -half_x..half_x {
77            let position = Vec2::new(x as f32, y as f32);
78            let translation = (position * tile_size).extend(rng.random::<f32>());
79            let rotation = Quat::from_rotation_z(rng.random::<f32>());
80            let scale = Vec3::splat(rng.random::<f32>() * 2.0);
81
82            sprites.push((
83                SpriteMesh {
84                    image: sprite_handle.clone(),
85                    custom_size: Some(tile_size),
86                    color: if color_tint.0 {
87                        COLORS[rng.random_range(0..3)]
88                    } else {
89                        Color::WHITE
90                    },
91                    ..default()
92                },
93                Transform {
94                    translation,
95                    rotation,
96                    scale,
97                },
98            ));
99        }
100    }
101    commands.spawn_batch(sprites);
102}
examples/stress_tests/bevymark_3d.rs (line 397)
350fn spawn_cubes(
351    commands: &mut Commands,
352    args: &Args,
353    counter: &mut BevyCounter,
354    spawn_count: usize,
355    cube_resources: &mut CubeResources,
356    waves_to_simulate: Option<usize>,
357    wave: usize,
358) {
359    let batch_material = cube_resources.materials[wave % cube_resources.materials.len()].clone();
360
361    let spawn_y = VOLUME_SIZE.y / 2.0 - HALF_CUBE_SIZE;
362    let spawn_z = -VOLUME_SIZE.z / 2.0 + HALF_CUBE_SIZE;
363
364    let batch = (0..spawn_count)
365        .map(|_| {
366            let spawn_pos = Vec3::new(
367                (cube_resources.transform_rng.random::<f32>() - 0.5) * VOLUME_SIZE.x,
368                spawn_y,
369                spawn_z,
370            );
371
372            let (transform, velocity) = cube_velocity_transform(
373                spawn_pos,
374                &mut cube_resources.velocity_rng,
375                waves_to_simulate,
376                FIXED_DELTA_TIME,
377            );
378
379            let material = if args.vary_per_instance {
380                cube_resources
381                    .materials
382                    .choose(&mut cube_resources.material_rng)
383                    .unwrap()
384                    .clone()
385            } else {
386                batch_material.clone()
387            };
388
389            (
390                Mesh3d(cube_resources.cube_mesh.clone()),
391                MeshMaterial3d(material),
392                transform,
393                Cube { velocity },
394            )
395        })
396        .collect::<Vec<_>>();
397    commands.spawn_batch(batch);
398
399    counter.count += spawn_count;
400    counter.color = Color::linear_rgb(
401        cube_resources.color_rng.random(),
402        cube_resources.color_rng.random(),
403        cube_resources.color_rng.random(),
404    );
405}
Source

pub fn queue(&mut self, command: impl Command)

Pushes a generic Command to the command queue.

If the Command returns a Result, it will be handled using the fallback error handler.

To use a custom error handler, see Commands::queue_handled.

The command can be:

  • A custom struct that implements Command.
  • A closure or function that matches one of the following signatures:
  • A built-in command from the command module.
§Example
#[derive(Resource, Default)]
struct Counter(u64);

struct AddToCounter(String);

impl Command for AddToCounter {
    type Out = Result;

    fn apply(self, world: &mut World) -> Result {
        let mut counter = world.get_resource_or_insert_with(Counter::default);
        let amount: u64 = self.0.parse()?;
        counter.0 += amount;
        Ok(())
    }
}

fn add_three_to_counter_system(mut commands: Commands) {
    commands.queue(AddToCounter("3".to_string()));
}

fn add_twenty_five_to_counter_system(mut commands: Commands) {
    commands.queue(|world: &mut World| {
        let mut counter = world.get_resource_or_insert_with(Counter::default);
        counter.0 += 25;
    });
}
Examples found in repository?
examples/app/settings.rs (line 127)
111fn change_count(
112    mut counter: ResMut<Counter>,
113    keyboard: Res<ButtonInput<KeyCode>>,
114    mut commands: Commands,
115) {
116    let mut changed = false;
117    if keyboard.just_pressed(KeyCode::Space) {
118        counter.count += 1;
119        changed = true;
120    }
121    if keyboard.just_pressed(KeyCode::Backspace) || keyboard.just_pressed(KeyCode::Delete) {
122        counter.count -= 1;
123        changed = true;
124    }
125
126    if changed {
127        commands.queue(SaveSettingsDeferred(Duration::from_secs_f32(0.1)));
128    }
129}
130
131fn on_window_close(mut close: MessageReader<WindowCloseRequested>, mut commands: Commands) {
132    // Save settings immediately, then quit.
133    if let Some(_close_event) = close.read().next() {
134        commands.queue(SaveSettingsSync::IfChanged);
135        commands.write_message(AppExit::Success);
136    }
137}
More examples
Hide additional examples
examples/window/persisting_window_settings.rs (line 111)
90fn update_window_settings(
91    mut move_events: MessageReader<WindowMoved>,
92    mut resize_events: MessageReader<WindowResized>,
93    windows: Query<&mut Window>,
94    window_settings: ResMut<WindowSettings>,
95    mut commands: Commands,
96) {
97    let Ok(window) = windows.single() else {
98        return;
99    };
100
101    let mut window_changed = false;
102    for _ in move_events.read() {
103        window_changed = true;
104    }
105
106    for _ in resize_events.read() {
107        window_changed = true;
108    }
109
110    if window_changed && store_window_settings(window_settings, window) {
111        commands.queue(SaveSettingsDeferred(Duration::from_secs_f32(0.5)));
112    }
113}
114
115fn store_window_settings(mut window_settings: ResMut<WindowSettings>, window: &Window) -> bool {
116    window_settings.set_if_neq(WindowSettings {
117        position: match window.position {
118            WindowPosition::At(pos) => Some(pos),
119            _ => None,
120        },
121        size: Some(UVec2::new(
122            window.resolution.width() as u32,
123            window.resolution.height() as u32,
124        )),
125        fullscreen: window.mode != WindowMode::Windowed,
126    })
127}
128
129fn on_window_close(mut close: MessageReader<WindowCloseRequested>, mut commands: Commands) {
130    // Save settings immediately, then quit.
131    if let Some(_close_event) = close.read().next() {
132        commands.queue(SaveSettingsSync::IfChanged);
133        commands.write_message(AppExit::Success);
134    }
135}
Source

pub fn queue_handled( &mut self, command: impl Command, error_handler: fn(BevyError, ErrorContext), )

Pushes a generic Command to the command queue.

If the Command returns a Result, the given error_handler will be used to handle error cases.

To implicitly use the fallback error handler, see Commands::queue.

The command can be:

§Example
use bevy_ecs::error::warn;

#[derive(Resource, Default)]
struct Counter(u64);

struct AddToCounter(String);

impl Command for AddToCounter {
    type Out = Result;

    fn apply(self, world: &mut World) -> Result {
        let mut counter = world.get_resource_or_insert_with(Counter::default);
        let amount: u64 = self.0.parse()?;
        counter.0 += amount;
        Ok(())
    }
}

fn add_three_to_counter_system(mut commands: Commands) {
    commands.queue_handled(AddToCounter("3".to_string()), warn);
}

fn add_twenty_five_to_counter_system(mut commands: Commands) {
    commands.queue(|world: &mut World| {
        let mut counter = world.get_resource_or_insert_with(Counter::default);
        counter.0 += 25;
    });
}
Examples found in repository?
examples/ecs/error_handling.rs (lines 186-197)
175fn failing_commands(mut commands: Commands) {
176    commands
177        // This entity doesn't exist!
178        .entity(Entity::from_raw_u32(12345678).unwrap())
179        // Normally, this failed command would panic,
180        // but since we've set the global error handler to `warn`
181        // it will log a warning instead.
182        .insert(Transform::default());
183
184    // The error handlers for commands can be set individually as well,
185    // by using the queue_handled method.
186    commands.queue_handled(
187        |world: &mut World| -> Result {
188            world
189                .get_resource::<UninitializedResource>()
190                .ok_or("Resource not initialized when accessed in a command")?;
191
192            Ok(())
193        },
194        |error, context| {
195            error!("{error}, {context}");
196        },
197    );
198}
Source

pub fn queue_silenced(&mut self, command: impl Command)

Pushes a generic Command to the queue like Commands::queue_handled, but instead silently ignores any errors.

Source

pub fn insert_batch<I, B>(&mut self, batch: I)
where I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static, B: Bundle, <B as DynamicBundle>::Effect: NoBundleEffect,

Adds a series of Bundles to each Entity they are paired with, based on a batch of (Entity, Bundle) pairs.

A batch can be any type that implements IntoIterator and contains (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This will overwrite any pre-existing components shared by the Bundle type. Use Commands::insert_batch_if_new to keep the pre-existing components instead.

This method is equivalent to iterating the batch and calling insert for each pair, but is faster by caching data that is shared between entities.

§Fallible

This command will fail if any of the given entities do not exist.

It will internally return a TryInsertBatchError, which will be handled by the fallback error handler.

Source

pub fn insert_batch_if_new<I, B>(&mut self, batch: I)
where I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static, B: Bundle, <B as DynamicBundle>::Effect: NoBundleEffect,

Adds a series of Bundles to each Entity they are paired with, based on a batch of (Entity, Bundle) pairs.

A batch can be any type that implements IntoIterator and contains (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This will keep any pre-existing components shared by the Bundle type and discard the new values. Use Commands::insert_batch to overwrite the pre-existing components instead.

This method is equivalent to iterating the batch and calling insert_if_new for each pair, but is faster by caching data that is shared between entities.

§Fallible

This command will fail if any of the given entities do not exist.

It will internally return a TryInsertBatchError, which will be handled by the fallback error handler.

Source

pub fn try_insert_batch<I, B>(&mut self, batch: I)
where I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static, B: Bundle, <B as DynamicBundle>::Effect: NoBundleEffect,

Adds a series of Bundles to each Entity they are paired with, based on a batch of (Entity, Bundle) pairs.

A batch can be any type that implements IntoIterator and contains (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This will overwrite any pre-existing components shared by the Bundle type. Use Commands::try_insert_batch_if_new to keep the pre-existing components instead.

This method is equivalent to iterating the batch and calling insert for each pair, but is faster by caching data that is shared between entities.

§Fallible

This command will fail if any of the given entities do not exist.

It will internally return a TryInsertBatchError, which will be handled by logging the error at the warn level.

Examples found in repository?
examples/2d/mesh2d_manual.rs (line 375)
332pub fn extract_colored_mesh2d(
333    mut commands: Commands,
334    mut previous_len: Local<usize>,
335    // When extracting, you must use `Extract` to mark the `SystemParam`s
336    // which should be taken from the main world.
337    query: Extract<
338        Query<
339            (
340                Entity,
341                RenderEntity,
342                &ViewVisibility,
343                &GlobalTransform,
344                &Mesh2d,
345            ),
346            With<ColoredMesh2d>,
347        >,
348    >,
349    mut render_mesh_instances: ResMut<RenderColoredMesh2dInstances>,
350) {
351    let mut values = Vec::with_capacity(*previous_len);
352    for (entity, render_entity, view_visibility, transform, handle) in &query {
353        if !view_visibility.get() {
354            continue;
355        }
356
357        let transforms = Mesh2dTransforms {
358            world_from_local: transform.affine().into(),
359            flags: MeshFlags::empty().bits(),
360        };
361
362        values.push((render_entity, ColoredMesh2d));
363        render_mesh_instances.insert(
364            entity.into(),
365            RenderMesh2dInstance {
366                mesh_asset_id: handle.0.id(),
367                transforms,
368                material_bind_group_id: Material2dBindGroupId::default(),
369                automatic_batching: false,
370                tag: 0,
371            },
372        );
373    }
374    *previous_len = values.len();
375    commands.try_insert_batch(values);
376}
Source

pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I)
where I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static, B: Bundle, <B as DynamicBundle>::Effect: NoBundleEffect,

Adds a series of Bundles to each Entity they are paired with, based on a batch of (Entity, Bundle) pairs.

A batch can be any type that implements IntoIterator and contains (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This will keep any pre-existing components shared by the Bundle type and discard the new values. Use Commands::try_insert_batch to overwrite the pre-existing components instead.

This method is equivalent to iterating the batch and calling insert_if_new for each pair, but is faster by caching data that is shared between entities.

§Fallible

This command will fail if any of the given entities do not exist.

It will internally return a TryInsertBatchError, which will be handled by logging the error at the warn level.

Source

pub fn init_resource<R>(&mut self)
where R: Resource + FromWorld,

Inserts a Resource into the World with an inferred value.

The inferred value is determined by the FromWorld trait of the resource. Note that any resource with the Default trait automatically implements FromWorld, and those default values will be used.

If the resource already exists when the command is applied, nothing happens.

§Example
#[derive(Resource, Default)]
struct Scoreboard {
    current_score: u32,
    high_score: u32,
}

fn initialize_scoreboard(mut commands: Commands) {
    commands.init_resource::<Scoreboard>();
}
Examples found in repository?
examples/shader_advanced/custom_phase_item.rs (line 211)
210fn prepare_custom_phase_item_buffers(mut commands: Commands) {
211    commands.init_resource::<CustomPhaseItemBuffers>();
212}
More examples
Hide additional examples
examples/diagnostics/log_diagnostics.rs (line 89)
58fn setup(
59    mut commands: Commands,
60    mut meshes: ResMut<Assets<Mesh>>,
61    mut materials: ResMut<Assets<StandardMaterial>>,
62) {
63    // circular base
64    commands.spawn((
65        Mesh3d(meshes.add(Circle::new(4.0))),
66        MeshMaterial3d(materials.add(Color::WHITE)),
67        Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
68    ));
69    // cube
70    commands.spawn((
71        Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
72        MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
73        Transform::from_xyz(0.0, 0.5, 0.0),
74    ));
75    // light
76    commands.spawn((
77        PointLight {
78            shadow_maps_enabled: true,
79            ..default()
80        },
81        Transform::from_xyz(4.0, 8.0, 4.0),
82    ));
83    // camera
84    commands.spawn((
85        Camera3d::default(),
86        Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
87    ));
88
89    commands.init_resource::<LogDiagnosticsFilters>();
90    commands.init_resource::<LogDiagnosticsStatus>();
91
92    commands.spawn((
93        LogDiagnosticsCommands,
94        Node {
95            top: px(5),
96            left: px(5),
97            flex_direction: FlexDirection::Column,
98            ..default()
99        },
100    ));
101}
Source

pub fn insert_resource<R>(&mut self, resource: R)
where R: Resource,

Inserts a Resource into the World with a specific value.

This will overwrite any previous value of the same resource type.

§Example
#[derive(Resource)]
struct Scoreboard {
    current_score: u32,
    high_score: u32,
}

fn system(mut commands: Commands) {
    commands.insert_resource(Scoreboard {
        current_score: 0,
        high_score: 0,
    });
}
Examples found in repository?
examples/audio/pitch.rs (line 22)
21fn setup(mut commands: Commands) {
22    commands.insert_resource(PitchFrequency(220.0));
23}
More examples
Hide additional examples
examples/async_tasks/async_channel_pattern.rs (line 91)
89fn setup_channel(mut commands: Commands) {
90    let (sender, receiver) = crossbeam_channel::unbounded();
91    commands.insert_resource(CubeChannel { sender, receiver });
92}
93
94/// A channel for communicating between async tasks and the main thread.
95#[derive(Resource)]
96struct CubeChannel {
97    sender: Sender<CubeFinished>,
98    receiver: Receiver<CubeFinished>,
99}
100
101/// Represents the completion of a cube task, containing the cube's transform
102#[derive(Debug)]
103struct CubeFinished {
104    transform: Transform,
105}
106
107/// Resource holding the mesh handle for the box (used for spawning cubes)
108#[derive(Resource, Deref)]
109struct BoxMeshHandle(Handle<Mesh>);
110
111/// Resource holding the material handle for the box (used for spawning cubes)
112#[derive(Resource, Deref)]
113struct BoxMaterialHandle(Handle<StandardMaterial>);
114
115/// Sets up the shared mesh and material for the cubes.
116fn setup_assets(
117    mut commands: Commands,
118    mut meshes: ResMut<Assets<Mesh>>,
119    mut materials: ResMut<Assets<StandardMaterial>>,
120) {
121    // Create and store a cube mesh
122    let box_mesh_handle = meshes.add(Cuboid::new(0.4, 0.4, 0.4));
123    commands.insert_resource(BoxMeshHandle(box_mesh_handle));
124
125    // Create and store a red material
126    let box_material_handle = materials.add(Color::srgb(1.0, 0.2, 0.3));
127    commands.insert_resource(BoxMaterialHandle(box_material_handle));
128}
examples/app/headless_renderer.rs (lines 314-316)
313fn image_copy_extract(mut commands: Commands, image_copiers: Extract<Query<&ImageCopier>>) {
314    commands.insert_resource(ImageCopiers(
315        image_copiers.iter().cloned().collect::<Vec<ImageCopier>>(),
316    ));
317}
examples/2d/texture_atlas.rs (line 34)
32fn load_textures(mut commands: Commands, asset_server: Res<AssetServer>) {
33    // Load multiple, individual sprites from a folder
34    commands.insert_resource(RpgSpriteFolder(asset_server.load_folder("textures/rpg")));
35}
examples/shader_advanced/custom_shader_instancing.rs (lines 243-246)
238fn init_custom_pipeline(
239    mut commands: Commands,
240    asset_server: Res<AssetServer>,
241    mesh_pipeline: Res<MeshPipeline>,
242) {
243    commands.insert_resource(CustomPipeline {
244        shader: asset_server.load(SHADER_ASSET_PATH),
245        mesh_pipeline: mesh_pipeline.clone(),
246    });
247}
examples/shader_advanced/custom_render_phase.rs (lines 174-177)
169fn init_stencil_pipeline(
170    mut commands: Commands,
171    mesh_pipeline: Res<MeshPipeline>,
172    asset_server: Res<AssetServer>,
173) {
174    commands.insert_resource(StencilPipeline {
175        mesh_pipeline: mesh_pipeline.clone(),
176        shader_handle: asset_server.load(SHADER_ASSET_PATH),
177    });
178}
Source

pub fn insert_resource_if_neq<R>(&mut self, resource: R)
where R: Resource + PartialEq,

Inserts a Resource into the World with a specific value if the resource is different or missing.

Source

pub fn remove_resource<R>(&mut self)
where R: Resource,

Removes a Resource from the World.

§Example
#[derive(Resource)]
struct Scoreboard {
    current_score: u32,
    high_score: u32,
}

fn system(mut commands: Commands) {
    commands.remove_resource::<Scoreboard>();
}
Examples found in repository?
examples/showcase/desk_toy.rs (line 267)
266fn end_drag(mut commands: Commands) {
267    commands.remove_resource::<DragOperation>();
268}
More examples
Hide additional examples
examples/asset/multi_asset_sync.rs (line 278)
271fn despawn_loading_state_entities(mut commands: Commands, loading: Query<Entity, With<Loading>>) {
272    // Despawn entities in the loading phase.
273    for entity in loading.iter() {
274        commands.entity(entity).despawn();
275    }
276
277    // Despawn resources used in the loading phase.
278    commands.remove_resource::<AssetBarrier>();
279    commands.remove_resource::<AsyncLoadingState>();
280}
Source

pub fn run_system(&mut self, id: impl Into<SystemId> + Send)

Runs the system corresponding to the given SystemId. Before running a system, it must first be registered via Commands::register_system or World::register_system.

The system is run in an exclusive and single-threaded way. Running slow systems can become a bottleneck.

There is no way to get the output of a system when run as a command, because the execution of the system happens later. To get the output of a system, use World::run_system or World::run_system_with instead of running the system as a command.

§Fallible

This command will fail if the given SystemId does not correspond to a System.

It will internally return a RegisteredSystemError, which will be handled by logging the error at the warn level.

Examples found in repository?
examples/ecs/callbacks.rs (line 51)
49fn run_callbacks(mut commands: Commands, query: Query<&Callback>) {
50    for callback in query.iter() {
51        commands.run_system(callback.system_id);
52    }
53}
More examples
Hide additional examples
examples/ecs/one_shot_systems.rs (line 77)
75fn evaluate_callbacks(query: Query<(Entity, &Callback), With<Triggered>>, mut commands: Commands) {
76    for (entity, callback) in query.iter() {
77        commands.run_system(callback.0);
78        commands.entity(entity).remove::<Triggered>();
79    }
80}
examples/showcase/loading_screen.rs (line 107)
98fn level_selection(
99    mut commands: Commands,
100    keyboard: Res<ButtonInput<KeyCode>>,
101    level_data: Res<LevelData>,
102    loading_state: Res<LoadingState>,
103) {
104    // Only trigger a load if the current level is fully loaded.
105    if let LoadingState::LevelReady = loading_state.as_ref() {
106        if keyboard.just_pressed(KeyCode::Digit1) {
107            commands.run_system(level_data.unload_level_id);
108            commands.run_system(level_data.level_1_id);
109        } else if keyboard.just_pressed(KeyCode::Digit2) {
110            commands.run_system(level_data.unload_level_id);
111            commands.run_system(level_data.level_2_id);
112        }
113    }
114}
Source

pub fn run_system_with<I>( &mut self, id: impl Into<SystemId<I>> + Send, input: <I as SystemInput>::Inner<'static>, )
where I: SystemInput + 'static, <I as SystemInput>::Inner<'static>: Send,

Runs the system corresponding to the given SystemId with input. Before running a system, it must first be registered via Commands::register_system or World::register_system.

The system is run in an exclusive and single-threaded way. Running slow systems can become a bottleneck.

There is no way to get the output of a system when run as a command, because the execution of the system happens later. To get the output of a system, use World::run_system or World::run_system_with instead of running the system as a command.

§Fallible

This command will fail if the given SystemId does not correspond to a System.

It will internally return a RegisteredSystemError, which will be handled by logging the error at the warn level.

Source

pub fn register_system<I, O, M>( &mut self, system: impl IntoSystem<I, O, M> + 'static, ) -> SystemId<I, O>
where I: SystemInput + Send + 'static, O: Send + 'static,

Registers a system and returns its SystemId so it can later be called by Commands::run_system or World::run_system.

This is different from adding systems to a Schedule, because the SystemId that is returned can be used anywhere in the World to run the associated system.

Using a Schedule is still preferred for most cases due to its better performance and ability to run non-conflicting systems simultaneously.

§Note

If the same system is registered more than once, each registration will be considered a different system, and they will each be given their own SystemId.

If you want to avoid registering the same system multiple times, consider using Commands::run_system_cached or storing the SystemId in a Local.

§Example
#[derive(Resource)]
struct Counter(i32);

fn register_system(
    mut commands: Commands,
    mut local_system: Local<Option<SystemId>>,
) {
    if let Some(system) = *local_system {
        commands.run_system(system);
    } else {
        *local_system = Some(commands.register_system(increment_counter));
    }
}

fn increment_counter(mut value: ResMut<Counter>) {
    value.0 += 1;
}
Examples found in repository?
examples/ecs/one_shot_systems.rs (line 43)
42fn setup_with_commands(mut commands: Commands) {
43    let system_id = commands.register_system(system_a);
44    commands.spawn((Callback(system_id), A));
45}
More examples
Hide additional examples
examples/showcase/loading_screen.rs (line 74)
72fn setup(mut commands: Commands) {
73    let level_data = LevelData {
74        unload_level_id: commands.register_system(unload_current_level),
75        level_1_id: commands.register_system(load_level_1),
76        level_2_id: commands.register_system(load_level_2),
77    };
78    commands.insert_resource(level_data);
79
80    // Spawns the UI that will show the user prompts.
81    let text_style = TextFont {
82        font_size: FontSize::Px(42.0),
83        ..default()
84    };
85    commands
86        .spawn((
87            Node {
88                justify_self: JustifySelf::Center,
89                align_self: AlignSelf::FlexEnd,
90                ..default()
91            },
92            BackgroundColor(Color::NONE),
93        ))
94        .with_child((Text::new("Press 1 or 2 to load a new scene."), text_style));
95}
examples/ecs/callbacks.rs (lines 23-25)
21fn setup_callbacks(mut commands: Commands) {
22    let trivial_callback = Callback {
23        system_id: commands.register_system(|| {
24            println!("This is the trivial callback system");
25        }),
26    };
27
28    let ordinary_system_callback = Callback {
29        system_id: commands.register_system(|query: Query<&Callback>| {
30            let n_callbacks = query.iter().len();
31            println!("This is the ordinary callback system. There are currently {n_callbacks} callbacks in the world.");
32        }),
33    };
34
35    let exclusive_callback = Callback {
36        system_id: commands.register_system(|world: &mut World| {
37            let n_entities = world.entities().len();
38            println!("This is the exclusive callback system. There are currently {n_entities} entities in the world.");
39        }),
40    };
41
42    commands.spawn(trivial_callback);
43    commands.spawn(ordinary_system_callback);
44    commands.spawn(exclusive_callback);
45}
Source

pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)
where I: SystemInput + Send + 'static, O: Send + 'static,

Removes a system previously registered with Commands::register_system or World::register_system.

After removing a system, the SystemId becomes invalid and attempting to use it afterwards will result in an error. Re-adding the removed system will register it with a new SystemId.

§Fallible

This command will fail if the given SystemId does not correspond to a System.

It will internally return a RegisteredSystemError, which will be handled by logging the error at the warn level.

Source

pub fn unregister_system_cached<I, O, M, S>(&mut self, system: S)
where I: SystemInput + Send + 'static, O: 'static, M: 'static, S: IntoSystem<I, O, M> + Send + 'static,

Removes a system previously registered with one of the following:

§Fallible

This command will fail if the given system is not currently cached in a CachedSystemId resource.

It will internally return a RegisteredSystemError, which will be handled by logging the error at the warn level.

Source

pub fn run_system_cached<M, S>(&mut self, system: S)
where M: 'static, S: IntoSystem<(), (), M> + Send + 'static,

Runs a cached system, registering it if necessary.

Unlike Commands::run_system, this method does not require manual registration.

The first time this method is called for a particular system, it will register the system and store its SystemId in a CachedSystemId resource for later.

If you would rather manage the SystemId yourself, or register multiple copies of the same system, use Commands::register_system instead.

§Limitations

This method only accepts ZST (zero-sized) systems to guarantee that any two systems of the same type must be equal. This means that closures that capture the environment, and function pointers, are not accepted.

If you want to access values from the environment within a system, consider passing them in as inputs via Commands::run_system_cached_with.

If that’s not an option, consider Commands::register_system instead.

Source

pub fn run_system_cached_with<I, M, S>( &mut self, system: S, input: <I as SystemInput>::Inner<'static>, )
where I: SystemInput + Send + 'static, <I as SystemInput>::Inner<'static>: Send, M: 'static, S: IntoSystem<I, (), M> + Send + 'static,

Runs a cached system with an input, registering it if necessary.

Unlike Commands::run_system_with, this method does not require manual registration.

To use the supplied input, the system should have a SystemInput as the first parameter.

The first time this method is called for a particular system, it will register the system and store its SystemId in a CachedSystemId resource for later.

If you would rather manage the SystemId yourself, or register multiple copies of the same system, use Commands::register_system instead.

§Limitations

This method only accepts ZST (zero-sized) systems to guarantee that any two systems of the same type must be equal. This means that closures that capture the environment, and function pointers, are not accepted.

If you want to access values from the environment within a system, consider passing them in as inputs.

If that’s not an option, consider Commands::register_system instead.

Source

pub fn trigger<'a>(&mut self, event: impl Event : Default>)
where <impl Event as Event>::Trigger<'a>: Default,

Triggers the given Event, which will run any Observers watching for it.

Examples found in repository?
examples/asset/asset_saving.rs (lines 195-198)
194fn on_drag_start(event: On<Pointer<DragStart>>, mut commands: Commands) {
195    commands.trigger(TryPlot {
196        entity: event.entity,
197        location: event.pointer_location.clone(),
198    });
199}
200
201fn on_drag(event: On<Pointer<Drag>>, mut commands: Commands) {
202    commands.trigger(TryPlot {
203        entity: event.entity,
204        location: event.pointer_location.clone(),
205    });
206}
More examples
Hide additional examples
examples/usage/context_menu.rs (line 66)
60fn setup(mut commands: Commands) {
61    commands.spawn(Camera2d);
62
63    commands.spawn(background_and_button()).observe(
64        // any click bubbling up here should lead to closing any open menu
65        |_: On<Pointer<Press>>, mut commands: Commands| {
66            commands.trigger(CloseContextMenus);
67        },
68    );
69}
70
71fn on_trigger_close_menus(
72    _event: On<CloseContextMenus>,
73    mut commands: Commands,
74    menus: Query<Entity, With<ContextMenu>>,
75) {
76    for e in menus.iter() {
77        commands.entity(e).despawn();
78    }
79}
80
81fn on_trigger_menu(event: On<OpenContextMenu>, mut commands: Commands) {
82    commands.trigger(CloseContextMenus);
83
84    let pos = event.pos;
85
86    debug!("open context menu at: {pos}");
87
88    commands
89        .spawn((
90            Name::new("context menu"),
91            ContextMenu,
92            Node {
93                position_type: PositionType::Absolute,
94                left: px(pos.x),
95                top: px(pos.y),
96                flex_direction: FlexDirection::Column,
97                border_radius: BorderRadius::all(px(4)),
98                ..default()
99            },
100            BorderColor::all(Color::BLACK),
101            BackgroundColor(Color::linear_rgb(0.1, 0.1, 0.1)),
102            children![
103                context_item("fuchsia", basic::FUCHSIA),
104                context_item("gray", basic::GRAY),
105                context_item("maroon", basic::MAROON),
106                context_item("purple", basic::PURPLE),
107                context_item("teal", basic::TEAL),
108            ],
109        ))
110        .observe(
111            |event: On<Pointer<Press>>,
112             menu_items: Query<&ContextMenuItem>,
113             mut clear_col: ResMut<ClearColor>,
114             mut commands: Commands| {
115                let target = event.original_event_target();
116
117                if let Ok(item) = menu_items.get(target) {
118                    clear_col.0 = item.0.into();
119                    commands.trigger(CloseContextMenus);
120                }
121            },
122        );
123}
124
125fn context_item(text: &str, col: Srgba) -> impl Bundle {
126    (
127        Name::new(format!("item-{text}")),
128        ContextMenuItem(col),
129        Button,
130        Node {
131            padding: UiRect::all(px(5)),
132            ..default()
133        },
134        children![(
135            Pickable::IGNORE,
136            Text::new(text),
137            TextFont {
138                font_size: FontSize::Px(24.0),
139                ..default()
140            },
141            TextColor(Color::WHITE),
142        )],
143    )
144}
145
146fn background_and_button() -> impl Bundle {
147    (
148        Name::new("background"),
149        Node {
150            width: percent(100),
151            height: percent(100),
152            align_items: AlignItems::Center,
153            justify_content: JustifyContent::Center,
154            ..default()
155        },
156        ZIndex(-10),
157        Children::spawn(SpawnWith(|parent: &mut RelatedSpawner<ChildOf>| {
158            parent
159                .spawn((
160                    Name::new("button"),
161                    Button,
162                    Node {
163                        width: px(250),
164                        height: px(65),
165                        border: UiRect::all(px(5)),
166                        justify_content: JustifyContent::Center,
167                        align_items: AlignItems::Center,
168                        border_radius: BorderRadius::MAX,
169                        ..default()
170                    },
171                    BorderColor::all(Color::BLACK),
172                    BackgroundColor(Color::BLACK),
173                    children![(
174                        Pickable::IGNORE,
175                        Text::new("Context Menu"),
176                        TextFont {
177                            font_size: FontSize::Px(28.0),
178                            ..default()
179                        },
180                        TextColor(Color::WHITE),
181                        TextShadow::default(),
182                    )],
183                ))
184                .observe(|mut event: On<Pointer<Press>>, mut commands: Commands| {
185                    // by default this event would bubble up further leading to the `CloseContextMenus`
186                    // event being triggered and undoing the opening of one here right away.
187                    event.propagate(false);
188
189                    debug!("click: {}", event.pointer_location.position);
190
191                    commands.trigger(OpenContextMenu {
192                        pos: event.pointer_location.position,
193                    });
194                });
195        })),
196    )
197}
examples/ecs/observer_propagation.rs (line 74)
70fn attack_armor(entities: Query<Entity, With<Armor>>, mut commands: Commands) {
71    let mut rng = rng();
72    if let Some(entity) = entities.iter().choose(&mut rng) {
73        let damage = rng.random_range(1..20);
74        commands.trigger(Attack { damage, entity });
75        info!("⚔️  Attack for {} damage", damage);
76    }
77}
examples/ui/scroll_and_overflow/scroll.rs (line 46)
27fn send_scroll_events(
28    mut mouse_wheel_reader: MessageReader<MouseWheel>,
29    hover_map: Res<HoverMap>,
30    keyboard_input: Res<ButtonInput<KeyCode>>,
31    mut commands: Commands,
32) {
33    for mouse_wheel in mouse_wheel_reader.read() {
34        let mut delta = -Vec2::new(mouse_wheel.x, mouse_wheel.y);
35
36        if mouse_wheel.unit == MouseScrollUnit::Line {
37            delta *= LINE_HEIGHT;
38        }
39
40        if keyboard_input.any_pressed([KeyCode::ControlLeft, KeyCode::ControlRight]) {
41            std::mem::swap(&mut delta.x, &mut delta.y);
42        }
43
44        for pointer_map in hover_map.values() {
45            for entity in pointer_map.keys().copied() {
46                commands.trigger(Scroll { entity, delta });
47            }
48        }
49    }
50}
examples/ui/navigation/directional_navigation.rs (lines 449-471)
439fn interact_with_focused_button(
440    action_state: Res<ActionState>,
441    input_focus: Res<InputFocus>,
442    mut commands: Commands,
443) {
444    if action_state
445        .pressed_actions
446        .contains(&DirectionalNavigationAction::Select)
447        && let Some(focused_entity) = input_focus.get()
448    {
449        commands.trigger(Pointer::new(
450            PointerId::Mouse,
451            Location {
452                target: NormalizedRenderTarget::None {
453                    width: 0,
454                    height: 0,
455                },
456                position: Vec2::ZERO,
457            },
458            Click {
459                button: PointerButton::Primary,
460                hit: HitData {
461                    camera: Entity::PLACEHOLDER,
462                    depth: 0.0,
463                    position: None,
464                    normal: None,
465                    extra: None,
466                },
467                count: 1,
468                duration: Duration::from_secs_f32(0.1),
469            },
470            focused_entity,
471        ));
472    }
473}
examples/ui/navigation/directional_navigation_overrides.rs (lines 842-864)
832fn interact_with_focused_button(
833    action_state: Res<ActionState>,
834    input_focus: Res<InputFocus>,
835    mut commands: Commands,
836) {
837    if action_state
838        .pressed_actions
839        .contains(&DirectionalNavigationAction::Select)
840        && let Some(focused_entity) = input_focus.get()
841    {
842        commands.trigger(Pointer::new(
843            PointerId::Mouse,
844            Location {
845                target: NormalizedRenderTarget::None {
846                    width: 0,
847                    height: 0,
848                },
849                position: Vec2::ZERO,
850            },
851            Click {
852                button: PointerButton::Primary,
853                hit: HitData {
854                    camera: Entity::PLACEHOLDER,
855                    depth: 0.0,
856                    position: None,
857                    normal: None,
858                    extra: None,
859                },
860                count: 1,
861                duration: Duration::from_secs_f32(0.1),
862            },
863            focused_entity,
864        ));
865    }
866}
Source

pub fn trigger_with<E>( &mut self, event: E, trigger: <E as Event>::Trigger<'static>, )
where E: Event, <E as Event>::Trigger<'static>: Send + Sync,

Triggers the given Event using the given Trigger, which will run any Observers watching for it.

Source

pub fn add_observer<M>( &mut self, observer: impl IntoObserver<M>, ) -> EntityCommands<'_>

Spawns an Observer and returns the EntityCommands associated with the entity that stores the observer.

observer can be any system whose first parameter is On.

Calling observe on the returned EntityCommands will observe the observer itself, which you very likely do not want.

§Panics

Panics if the given system is an exclusive system.

Source

pub fn write_message<M>(&mut self, message: M) -> &mut Commands<'w, 's>
where M: Message,

Writes an arbitrary Message.

This is a convenience method for writing messages without requiring a MessageWriter.

§Performance

Since this is a command, exclusive world access is used, which means that it will not profit from system-level parallelism on supported platforms.

If these messages are performance-critical or very frequently sent, consider using a MessageWriter instead.

Examples found in repository?
tests/window/desktop_request_redraw.rs (line 105)
103fn redraw(mut commands: Commands, query: Query<Entity, With<AnimationActive>>) {
104    if query.iter().next().is_some() {
105        commands.write_message(RequestRedraw);
106    }
107}
More examples
Hide additional examples
examples/app/settings.rs (line 135)
131fn on_window_close(mut close: MessageReader<WindowCloseRequested>, mut commands: Commands) {
132    // Save settings immediately, then quit.
133    if let Some(_close_event) = close.read().next() {
134        commands.queue(SaveSettingsSync::IfChanged);
135        commands.write_message(AppExit::Success);
136    }
137}
examples/window/persisting_window_settings.rs (line 133)
129fn on_window_close(mut close: MessageReader<WindowCloseRequested>, mut commands: Commands) {
130    // Save settings immediately, then quit.
131    if let Some(_close_event) = close.read().next() {
132        commands.queue(SaveSettingsSync::IfChanged);
133        commands.write_message(AppExit::Success);
134    }
135}
examples/3d/clustered_decals.rs (line 166)
154fn setup(
155    mut commands: Commands,
156    asset_server: Res<AssetServer>,
157    app_status: Res<AppStatus>,
158    render_device: Res<RenderDevice>,
159    render_adapter: Res<RenderAdapter>,
160    mut meshes: ResMut<Assets<Mesh>>,
161    mut materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, CustomDecalExtension>>>,
162) {
163    // Error out if clustered decals aren't supported on the current platform.
164    if !decal::clustered::clustered_decals_are_usable(&render_device, &render_adapter) {
165        error!("Clustered decals aren't usable on this platform.");
166        commands.write_message(AppExit::error());
167    }
168
169    spawn_cube(&mut commands, &mut meshes, &mut materials);
170    spawn_camera(&mut commands);
171    spawn_light(&mut commands);
172    spawn_decals(&mut commands, &asset_server);
173    spawn_buttons(&mut commands);
174    spawn_help_text(&mut commands, &app_status);
175}
examples/3d/light_textures.rs (line 155)
143fn setup(
144    mut commands: Commands,
145    asset_server: Res<AssetServer>,
146    app_status: Res<AppStatus>,
147    render_device: Res<RenderDevice>,
148    render_adapter: Res<RenderAdapter>,
149    mut meshes: ResMut<Assets<Mesh>>,
150    mut materials: ResMut<Assets<StandardMaterial>>,
151) {
152    // Error out if clustered decals (and so light textures) aren't supported on the current platform.
153    if !decal::clustered::clustered_decals_are_usable(&render_device, &render_adapter) {
154        error!("Light textures aren't usable on this platform.");
155        commands.write_message(AppExit::error());
156    }
157
158    spawn_cubes(&mut commands, &mut meshes, &mut materials);
159    spawn_camera(&mut commands);
160    spawn_light(&mut commands, &asset_server);
161    spawn_buttons(&mut commands);
162    spawn_help_text(&mut commands, &app_status);
163    spawn_light_textures(&mut commands, &asset_server, &mut meshes, &mut materials);
164}
Source

pub fn run_schedule(&mut self, label: impl ScheduleLabel)

Runs the schedule corresponding to the given ScheduleLabel.

Calls World::try_run_schedule.

§Fallible

This command will fail if the given ScheduleLabel does not correspond to a Schedule.

It will internally return a TryRunScheduleError, which will be handled by logging the error at the warn level.

§Example
#[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]
struct FooSchedule;

commands.run_schedule(FooSchedule);

Trait Implementations§

Source§

impl<'w, 's> CommandsSceneExt for Commands<'w, 's>

Source§

fn spawn_scene<S>(&mut self, scene: S) -> EntityCommands<'_>
where S: Scene,

Spawns the given Scene as soon as Commands are applied. This will resolve the Scene (using Scene::resolve). If that fails (for example, if there are dependencies that have not been loaded yet), it will log a SpawnSceneError as an error. If resolving the Scene is successful, the scene will be spawned. Read more
Source§

fn queue_spawn_scene<S>(&mut self, scene: S) -> EntityCommands<'_>
where S: Scene,

Queues the scene to be spawned. This will evaluate the scene’s dependencies (via Scene::register_dependencies) and queue it to be resolved and spawned after all of the dependencies have been loaded. If a SpawnSceneError occurs, it will be logged as an error. Read more
Source§

fn spawn_scene_list<L>(&mut self, scenes: L)
where L: SceneList,

Spawns the given SceneList as soon as Commands are applied. This will resolve the scene list (using SceneList::resolve_list). If that fails (for example, if there are dependencies that have not been loaded yet), it will log a SpawnSceneError as an error. If resolving the Scene is successful, the scene list will be spawned. Read more
Source§

fn queue_spawn_scene_list<L>(&mut self, scenes: L)
where L: SceneList,

Queues the scene_list to be spawned. This will evaluate the scene_list’s dependencies (via Scene::register_dependencies) and queue it to be resolved and spawned after all of the dependencies have been loaded. If a SpawnSceneError occurs, it will be logged as an error. Read more
Source§

impl CommandsStatesExt for Commands<'_, '_>

Source§

fn set_state<S>(&mut self, state: S)

Sets the next state the app should move to. Read more
Source§

fn set_state_if_neq<S>(&mut self, state: S)

Sets the next state the app should move to, skipping any state transitions if the next state is the same as the current state. Read more
Source§

impl<'w, 's> DelayedCommandsExt<'w> for Commands<'w, 's>

Source§

fn delayed(&mut self) -> DelayedCommands<'w, '_>

Returns a DelayedCommands instance that can be used to queue commands to be submitted at a later point in time. Read more
Source§

impl<'w, 's> ReadOnlySystemParam for Commands<'w, 's>

Source§

impl Send for Commands<'_, '_>

Source§

impl Sync for Commands<'_, '_>

Source§

impl SystemParam for Commands<'_, '_>

Source§

type State = FetchState

Used to store data which persists across invocations of a system.
Source§

type Item<'w, 's> = Commands<'w, 's>

The item type returned when constructing this system param. The value of this associated type should be Self, instantiated with new lifetimes. Read more
Source§

fn init_state(world: &mut World) -> <Commands<'_, '_> as SystemParam>::State

Creates a new instance of this param’s State.
Source§

fn init_access( state: &<Commands<'_, '_> as SystemParam>::State, system_meta: &mut SystemMeta, component_access_set: &mut FilteredAccessSet, world: &mut World, )

Registers any World access used by this SystemParam. Read more
Source§

fn apply( state: &mut <Commands<'_, '_> as SystemParam>::State, system_meta: &SystemMeta, world: &mut World, )

Applies any deferred mutations stored in this SystemParam’s state. This is used to apply Commands during ApplyDeferred.
Source§

fn queue( state: &mut <Commands<'_, '_> as SystemParam>::State, system_meta: &SystemMeta, world: DeferredWorld<'_>, )

Queues any deferred mutations to be applied at the next ApplyDeferred.
Source§

unsafe fn get_param<'w, 's>( state: &'s mut <Commands<'_, '_> as SystemParam>::State, system_meta: &SystemMeta, world: UnsafeWorldCell<'w>, change_tick: Tick, ) -> Result<<Commands<'_, '_> as SystemParam>::Item<'w, 's>, SystemParamValidationError>

Creates a parameter to be passed into a SystemParamFunction. Read more

Auto Trait Implementations§

§

impl<'w, 's> !UnwindSafe for Commands<'w, 's>

§

impl<'w, 's> Freeze for Commands<'w, 's>

§

impl<'w, 's> RefUnwindSafe for Commands<'w, 's>

§

impl<'w, 's> Unpin for Commands<'w, 's>

§

impl<'w, 's> UnsafeUnpin for Commands<'w, 's>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> InitializeFromFunction<T> for T

Source§

fn initialize_from_function(f: fn() -> T) -> T

Create an instance of this type from an initialization function
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoResult<T> for T

Source§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<Ret> SpawnIfAsync<(), Ret> for Ret

Source§

fn spawn(self) -> Ret

Spawn the value into the dioxus runtime if it is an async block
Source§

impl<T, O> SuperFrom<T> for O
where O: From<T>,

Source§

fn super_from(input: T) -> O

Convert from a type to another type.
Source§

impl<T, O, M> SuperInto<O, M> for T
where O: SuperFrom<T, M>,

Source§

fn super_into(self) -> O

Convert from a type to another type.
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more