#gamedev #bevy #mouse #input


A plugin for effortless mouse tracking in the bevy game engine

13 unstable releases (6 breaking)

0.7.0 Nov 24, 2023
0.6.0 Jul 14, 2023
0.5.3 Jan 27, 2023
0.5.0 Nov 24, 2022
0.1.1 Feb 23, 2021

#392 in Game dev

Download history 75/week @ 2023-11-04 47/week @ 2023-11-11 97/week @ 2023-11-18 127/week @ 2023-11-25 57/week @ 2023-12-02 83/week @ 2023-12-09 76/week @ 2023-12-16 86/week @ 2023-12-23 55/week @ 2023-12-30 104/week @ 2024-01-06 75/week @ 2024-01-13 60/week @ 2024-01-20 92/week @ 2024-01-27 67/week @ 2024-02-03 93/week @ 2024-02-10 299/week @ 2024-02-17

554 downloads per month

MIT license

224 lines


CI bevy_mouse_tracking on crates.io bevy_mouse_tracking docs


Bevy Version Crate Version
0.12 0.7
0.11 0.6
0.9 0.5
0.8 0.4
0.7 0.2.1
0.6 0.2.0
main branch main branch

This crate aims to make mouse tracking both effortless and explicit. Tracking is opt-in and handled opaquely by this plugin.

The mouse can be tracked on a per-camera basis by querying for tracking components. Additionally, a global resource is maintained that tracks the main camera, if applicable.


use bevy::prelude::*;
use bevy_mouse_tracking_plugin::prelude::*;

// First, add the plugin to your `App`.

    .add_plugins((DefaultPlugins, MousePosPlugin))
    .add_systems(Startup, setup)
    .add_systems(Update, dbg_mouse)
    // ...

fn setup(mut commands: Commands) {
        // Spawn a camera bundle
        // Opt in to mouse tracking.
        // `InitMouseTracking` is a command that adds the mouse tracking
        // component to the camera with a correct initial value.

// Now, we can track the mouse position by querying for it.

use bevy_mouse_tracking_plugin::MousePos;

fn dbg_mouse(mouse: Query<&MousePos>) {
    // This will print the screen-space location of the mouse on every frame.
    eprintln!("{}", *mouse.single());
    // If we did `mouse.iter()` instead, this will naturally work for multiple cameras.

Having to call Query::single is a bit annoying, and potentially error-prone. Instead, we can specify a main camera, which the plugin will treat specially.

use bevy_mouse_tracking_plugin::MainCamera;

fn setup(mut commands: Commands) {
        // Spawn a camera with tracking.
        // Add a component to mark it as the main camera.

// Now that we've specified the main camera, we can get the mouse position using a global resource.

fn dbg_mouse(mouse: Res<MousePos>) {
    // This will print the screen-space location of the mouse on every frame.
    eprintln!("{}", *mouse);


We can do better than just screen-space: this crate supports automatic transformation to world-space coordinates via MousePosWorld -- this is can be accessed as either a component or a resource.

use bevy_mouse_tracking_plugin::MousePosWorld;

fn setup(mut commands: Commands) {
        // Opt in to world-space mouse tracking.
        // This will automatically opt into screen-space tracking.
        // ...

// Getting the world-space position using a query.
fn dbg_world_single(mouse: Query<&MousePosWorld>) {
    // This will print the world-space position of the mouse on every frame.
    eprintln!("{}", *mouse.single());

// Getting it using the resource.
fn dbg_world_res(mouse: Res<MousePosWorld>) {
    eprintln!("{}", *mouse);

Note that this is only supported for two-dimensional, orthographic cameras, but pull requests for 3D support are welcome!

If you do not specify a MainCamera, the MousePos and MousePosWorld resources will still exist, but they will always be zero.

Mouse motion

This crate supports a resource that tracks mouse motion, via MouseMotionPlugin. The motion can be accessed from any system in a MouseMotion resource.

Crate name

As a final aside: the name of this crate is intentionally verbose, since it is very likely that this crate will eventually be made redundant by future updates to Bevy.
I recommend renaming the crate in your Cargo.toml:

mouse_tracking = { package = "bevy_mouse_tracking_plugin", version = "..." }

License: MIT


~1M SLoC