鼠标

可参考的官方例子: mouse_input, mouse_input_events.


鼠标按键

键盘输入类似,鼠标按键也可以作为一种输入状态资源,以及事件

你可以使用 Input<MouseButton> 检查特定鼠标按键的状态:

fn mouse_button_input(
    buttons: Res<Input<MouseButton>>,
) {
    if buttons.just_pressed(MouseButton::Left) {
        // Left button was pressed
    }
    if buttons.just_released(MouseButton::Left) {
        // Left Button was released
    }
    if buttons.pressed(MouseButton::Right) {
        // Right Button is being held down
    }
}

要获得所有的按压/释放动作,使用 MouseButtonInput 事件

fn mouse_button_events(
    mut mousebtn_evr: EventReader<MouseButtonInput>,
) {
    use bevy::input::ElementState;

    for ev in mousebtn_evr.iter() {
        match ev.state {
            ElementState::Pressed => {
                println!("Mouse button press: {:?}", ev.button);
            }
            ElementState::Released => {
                println!("Mouse button release: {:?}", ev.button);
            }
        }
    }
}

鼠标滚动和滚轮

为了检测滚动输入,使用 MouseWheel 事件

fn scroll_events(
    mut scroll_evr: EventReader<MouseWheel>,
) {
    use bevy::input::mouse::MouseScrollUnit;
    for ev in scroll_evr.iter() {
        match ev.unit {
            MouseScrollUnit::Line => {
                println!("Scroll (line units): vertical: {}, horizontal: {}", ev.y, ev.x);
            }
            MouseScrollUnit::Pixel => {
                println!("Scroll (pixel units): vertical: {}, horizontal: {}", ev.y, ev.x);
            }
        }
    }
}

MouseScrollUnit 枚举很重要:它告诉你滚动输入的类型。Line 是用于有固定滚动步长的设备,比如桌面电脑鼠标上的滚轮。Pixel 用于具有平滑(细粒度)滚动的硬件,如笔记本的触控板。

你应该以不同的方式来处理这两种类型的硬件(用不同的灵敏度设置),以便为这两种类型的硬件提供良好的体验。

鼠标移动

如果你不关心鼠标光标的确切位置,而只是想看看它从一帧到另一帧的移动量,就使用 MouseMotion 事件 就对了。这对于控制 3D 摄像机等事情很有用。

每当鼠标被移动时,你会收到一个带有 delta 数据的事件。

fn mouse_motion(
    mut motion_evr: EventReader<MouseMotion>,
) {
    for ev in motion_evr.iter() {
        println!("Mouse moved: X: {} px, Y: {} px", ev.delta.x, ev.delta.y);
    }
}

你或许还想在游戏窗口内抓住/锁定鼠标

鼠标光标位置

如果你想准确地跟踪指针/光标的位置,请使用这个功能。这对诸如在你的游戏或 UI 上点击和悬停某个东西的应用场景非常有用。

你可以从相应的窗口中获得鼠标指针的当前坐标(如果鼠标当前正处在该窗口内)。

fn cursor_position(
    windows: Res<Windows>,
) {
    // Games typically only have one window (the primary window).
    // For multi-window applications, you need to use a specific window ID here.
    let window = windows.get_primary().unwrap();

    if let Some(_position) = window.cursor_position() {
        // cursor is inside the window, position given
    } else {
        // cursor is not inside the window
    }
}

为了检测光标何时被移动,使用 CursorMoved events 来获得新的坐标。

fn cursor_events(
    mut cursor_evr: EventReader<CursorMoved>,
) {
    for ev in cursor_evr.iter() {
        println!(
            "New cursor position: X: {}, Y: {}, in Window ID: {:?}",
            ev.position.x, ev.position.y, ev.id
        );
    }
}

注意,你只能获得鼠标在游戏窗口内的位置,你不能获得鼠标在整个操作系统桌面或屏幕上的全局位置。

要跟踪鼠标光标何时进入和离开你的窗口,可以使用 CursorEnteredCursorLeft 事件