Search code examples
rustgame-developmentbevy

How to read mouse motion in bevy?


I want to create a first person camera. I already researched the source code of several other implementations like

https://github.com/mcpar-land/bevy_fly_camera

https://github.com/sburris0/bevy_flycam

But when implementing it by my own(mostly copy paste tbh) it fails to compile, when using the latest bevy version on git.

Compile output:

error[E0277]: `*mut (usize, PhantomData<MouseMotion>)` cannot be sent between threads safely
   --> src/player_input.rs:151:13
    |
151 |     mut state: ResMut<State>,
    |                ^^^^^^^^^^^^^ `*mut (usize, PhantomData<MouseMotion>)` cannot be sent between threads safely
    | 
   ::: /home/luca/.cargo/git/checkouts/bevy-f7ffde730c324c74/89a41bc/crates/bevy_ecs/src/resource/resource_query.rs:66:26
    |
66  | pub struct ResMut<'a, T: Resource> {
    |                          -------- required by this bound in `bevy::prelude::ResMut`
    |
    = help: within `player_input::State<'_>`, the trait `Send` is not implemented for `*mut (usize, PhantomData<MouseMotion>)`
    = note: required because it appears within the type `Local<'_, (usize, PhantomData<MouseMotion>)>`
    = note: required because it appears within the type `bevy::prelude::EventReader<'_, MouseMotion>`
    = note: required because it appears within the type `player_input::State<'_>`
    = note: required because of the requirements on the impl of `Resource` for `player_input::State<'_>`

Here is the code:

#[derive(Default)]
struct State<'a> {
    mouse_motion_event_reader: EventReader<'a, MouseMotion>,
}

fn mouse_motion_system(
    time: Res<Time>,

    mut state: ResMut<State>, //<-- IMPORTANT LINE (Line 151)

    mouse_motion_events: Res<Events<MouseMotion>>,
    mut query: Query<(&mut FlyCamera, &mut Transform)>,
) {
    //...
}

It only throws this error on the latest version of bevy and not on version 0.4.0.

Did I do something wrong or should I open an issue on github because it's the engine's fault?

What do I have to do to make it work?


Solution

  • You should not have EventReader in State here at all. Maybe you wanted to keep track of the last cursor position inside the state?

    Since the event API was simplified for Bevy 0.5 you only need the EventReader as system parameter; mouse_motion_events: Res<Events<MouseMotion>>, is now obsolete and can be replaced with mut mouse_motion_events: EventReader<MouseMotion>.