Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In the Bevy Engine, how do I use &mut queries in the for-each system?

Tags:

rust

bevy

When extending a basic example with the mutating of a component, I tried adding &mut to a component parameter in a system. However, this triggered the no method "system" found error.

My code is here:

use bevy::prelude::*;

  fn setup(
      mut commands: Commands,
      asset_server: Res<AssetServer>,
      mut materials: ResMut<Assets<ColorMaterial>>,
  ) {
      let texture_handle = asset_server.load("icon.png").unwrap();
      commands
          .spawn(Camera2dComponents::default())
          .spawn(SpriteComponents {
              material: materials.add(texture_handle.into()),
              rotation: Rotation::from_rotation_z(0.0),
              ..Default::default()
          })
          .with(Player(0.0))
          .with(());
  }

  struct Player(f32);

  fn control_system(keyboard_input: Res<Input<KeyCode>>, player: &mut Player) { // <- mut added here
      let mut r = player.0;
      println!("hello");

      /*
      if keyboard_input.pressed(KeyCode::Left) {
          player.0 += 0.1;
      }

      if keyboard_input.pressed(KeyCode::Right) {
          player.0 -= 0.1;
      }
      */
  }

  fn main() {
      App::build()
          .add_default_plugins()
          .add_startup_system(setup.system())
          .add_system(control_system.system())
          .run();
  }

Looking at Into foreach system I admit that I don't fully understand how or why this doesn't work, so maybe I'm missing something basic!

Did I make a simple mistake? Are people doing stuff to work around this?

Thanks!

like image 535
Ty Overby Avatar asked Oct 20 '25 02:10

Ty Overby


1 Answers

We chose to use Mut<T> pointers exclusively in Bevy ECS because they let us track whenever a component has changed. This is what makes our "change tracking" queries work.

Query<&mut T> actually also returns a Mut<T> pointer.

We actually initially supported &mut T in for-each systems, but this returns an actual &mut T reference, which prevents us from tracking mutations of T. This creates a situation where people using &mut T can no longer trust the result of "change queries" like Changed<T>. Giving people the ability to accidentally (or intentionally) break out of change tracking didn't seem worth the slightly more intuitive &mut T in systems.

Mut<T> is a slightly non-standard api that enables really cool features. Its something many new users will hit once and think "ok thats a bit odd", but then they never need to think about it again.

like image 171
cart Avatar answered Oct 22 '25 03:10

cart



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!