Giter VIP home page Giter VIP logo

bevy-mouse-tracking's Introduction

bevy_mouse_tracking_plugin

CI bevy_mouse_tracking on crates.io bevy_mouse_tracking docs

Versions

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.

Basics

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

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

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


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

// 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) {
    commands
        // Spawn a camera with tracking.
        .spawn(Camera2dBundle::default())
        .add(InitMouseTracking)
        // Add a component to mark it as the main camera.
        .insert(MainCamera);
}

// 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);
}

World-space

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) {
    commands
        .spawn(Camera2dBundle::default())
        // Opt in to world-space mouse tracking.
        // This will automatically opt into screen-space tracking.
        .add(InitWorldTracking)
        // ...
}

// 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:

[dependencies]
mouse_tracking = { package = "bevy_mouse_tracking_plugin", version = "..." }

License: MIT

bevy-mouse-tracking's People

Contributors

chrisburnor avatar dauthdaert avatar emmettjayhart avatar iiiii7d avatar jojojet avatar ttarabbia avatar xlambein avatar zdimension avatar zyansheep avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

bevy-mouse-tracking's Issues

MousePosWorld does not respect OrthographicProjection::scale

To reproduce adjust OrthographicProjection::scale in the world.rs example:

diff --git a/examples/world.rs b/examples/world.rs
index 9651928..889331a 100644
--- a/examples/world.rs
+++ b/examples/world.rs
@@ -22,7 +22,9 @@ fn main() {

 fn setup(mut commands: Commands, asset_server: Res<AssetServer>, window: Res<WindowDescriptor>) {
     // Spawn a Camera
-    commands.spawn_bundle(OrthographicCameraBundle::new_2d());
+    let mut camera_bundle = OrthographicCameraBundle::new_2d();
+    camera_bundle.orthographic_projection.scale = 0.5;
+    commands.spawn_bundle(camera_bundle);

     // Reference for the origin
     commands.spawn_bundle(SpriteBundle {
MousePosWorld.mp4

Conflict between UiCamera and OrthographicCamera

The current camera query for the update_post_orth system doesn't distinguish which camera is being queried. This is because both UiCameraBundle and OrthographicCameraBundle implement the exact same components, with the exception of the Frustum component on Orthographic Camera.

This leads to bugs given the different coordinate systems of different cameras. UI Cameras have origin in lower left while regular orthographic cameras origin is in the center of the screen.

Current workaround is to filter out non-UI camera via Frustum component until bevyengine/bevy#1854 is addressed.

However, given Bevy's support for multiple windows and cameras, this plugin should implement a means by which the MousePosWorld can be retrieved for any arbitrary camera.

Add a minimal prelude

There should be a small prelude, with re-exports of extension traits.

Open question: should this include common types, in addition to traits?

UI is broken in the examples

Both examples (screen and world) used for this crate have broken UI. The text elements that show the current mouse position do not properly adhere to the left edge of the screen: they are cut in half, or do not appear at all depending on what screen size is used.

1-frame lag for mouse tracking

There appears to be a slight lag with mouse tracking -- this should be fixed before the next release.

I suspect that this is due to the resources being updated in CoreStage::First, which occurs before the event bevy_window::CursorMoved gets sent.

Error attempting to use MouseMotionPlugin

Adding MouseMotionPlugin results in the following upon running:

2023-01-08T20:41:06.917844Z  WARN bevy_ecs::schedule::graph_utils: bevy_mouse_tracking_plugin::mouse_motion::update_mouse_motion wants to be after unknown label: bevy_ecs::event::Events<bevy_mouse_tracking_plugin::mouse_motion::MouseMotion>::update_system
thread 'Compute Task Pool (4)' panicked at 'Resource requested by bevy_mouse_tracking_plugin::mouse_motion::update_mouse_motion does not exist: bevy_ecs::event::Events<bevy_mouse_tracking_plugin::mouse_motion::MouseMotion>'

Revamp examples to use multiple cameras

The current examples are based on the old design of the plugin, whose main distinction was between screen-space and world-space. Now, the main distinction is between single-camera and multi-camera, so the examples should be rewritten to reflect this.

Ideas for a revamp

Some unorganized thoughts before I forget them. Opinions welcome

  • MainCamera is now a resource containing the Entity ID of the desired main camera. If this resource is defined, then the MousePos* resources will automagically get filled in. Making it a resource ensures it's a singleton, so we don't need to error when multiple are defined.
  • Mouse tracking is now opt-in. If you want mouse tracking for a camera, you need to add a specific component to it. This is more ECS idiomatic, and compatible with other plugins by default.
  • Rename MousePos to MousePosWindow, make it work with camera-driven rendering. When "windows as entities" gets merged in Bevy main, this should be removed entirely probably.

integration in my game

Hello, could you fork my project here and show how it does work with your library, thats exactly the tool i was looking for !
The previous alternative i found was
https://github.com/anshorei/bevy_rei/tree/HEAD/bevy_interact_2d
but only works on bevy0.5

i need to get datas about hovered entities (maybe with a tooltip ?) but above all select single entity by clicking on it,
and make squad of entities while click and drag upon them.

Hope you can do something with it ...

https://github.com/pyweeker/Bevy_and_Egui

Incompatible with kayak_ui (and other cameras with custom projections)

This crate does not work with the kayak_ui crate due to its use of a custom projection.

Even with a MainCamera given to a standard bevy camera and no user-defined interaction between this crate and the kayak_ui camera, it is still considered when querying for cameras and thus this plugin panics with 'only orthographic cameras are supported' when ideally it shouldn't be forced to.

I am not saying this crate needs to support custom cameras, but having the option to manually opt-out for a custom camera so that the app can use both plugins separately is something I believe should be added.

I will open a PR to fix this issue.

MouseMotion delta is always 0

Mouse Pos: Res(MousePosWorld(Vec3(818.5631, 597.5603, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(831.4444, 568.5211, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(832.2333, 545.9696, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(805.8806, 524.8297, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(778.9986, 514.34753, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(732.9863, 508.825, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(707.8209, 510.93866, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(684.2678, 532.23425, 999.9)))
Mouse Motion: Res(MouseMotion { delta: Vec2(0.0, 0.0) })
Mouse Pos: Res(MousePosWorld(Vec3(681.78625, 562.62366, 999.9)))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.