use bevy::{prelude::*, window::PrimaryWindow}; pub struct PointerPlugin; impl Plugin for PointerPlugin { fn build(&self, app: &mut App) { app.init_resource::() .add_systems(Update, update_pointer_target); } } /// World position of the active touch or mouse cursor, if any. #[derive(Resource, Default)] pub struct PointerTarget(pub Option); fn update_pointer_target( window: Single<&Window, With>, camera: Single<(&Camera, &GlobalTransform)>, touches: Res, mut target: ResMut, ) { let (camera, camera_transform) = *camera; // Touch and cursor positions are both in logical window pixels target.0 = touches .first_pressed_position() .or_else(|| window.cursor_position()) .and_then(|position| camera.viewport_to_world_2d(camera_transform, position).ok()); }