Fix ui picking outside the viewport (#19744)
# Objective Fixes #19692 ## Solution - Skip pointers outside the viewport. ## Testing Tested with the following example: <details> <summary>Click to expand code</summary> ```rust use bevy::{ prelude::*, render:📷:Viewport, window::SystemCursorIcon, winit::cursor::CursorIcon, }; fn main() -> AppExit { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .insert_resource(ClearColor(Color::BLACK)) .run() } fn setup(mut commands: Commands, window: Single<&Window>) { // commands.spawn(( Camera2d, Camera { clear_color: ClearColorConfig::Custom(Color::WHITE), viewport: Some(Viewport { physical_position: UVec2::new( window.physical_width() / 4, window.physical_height() / 4, ), physical_size: UVec2::new( window.physical_width() / 2, window.physical_height() / 2, ), ..default() }), ..default() }, )); commands .spawn(( Node { top: Val::Px(100.0), left: Val::Px(100.0), width: Val::Px(200.0), height: Val::Px(200.0), ..default() }, BackgroundColor(Color::srgb(1.0, 0.0, 0.0)), )) .observe(|trigger: On<Pointer<Drag>>, mut node: Query<&mut Node>| { let mut node = node.get_mut(trigger.target()).unwrap(); node.left = Val::Px(px(node.left) + trigger.delta.x); node.top = Val::Px(px(node.top) + trigger.delta.y); }) .observe( |_: On<Pointer<DragStart>>, window: Single<Entity, With<Window>>, mut commands: Commands| { commands .entity(*window) .insert(CursorIcon::from(SystemCursorIcon::Grabbing)); }, ) .observe( |_: On<Pointer<DragEnd>>, window: Single<Entity, With<Window>>, mut commands: Commands| { commands.entity(*window).remove::<CursorIcon>(); }, ); } fn px(val: Val) -> f32 { match val { Val::Px(px) => px, _ => 0.0, } } ``` </details> ## Additional information This is at least also broken on the sprite picking backend. I guess the fix for other backends are also trivial if this is correct. (Sprite picking: #19747)
This commit is contained in:
parent
169254b938
commit
83afcb5a2b
@ -140,6 +140,10 @@ pub fn ui_picking(
|
||||
let mut pointer_pos =
|
||||
pointer_location.position * camera_data.target_scaling_factor().unwrap_or(1.);
|
||||
if let Some(viewport) = camera_data.physical_viewport_rect() {
|
||||
if !viewport.as_rect().contains(pointer_pos) {
|
||||
// The pointer is outside the viewport, skip it
|
||||
continue;
|
||||
}
|
||||
pointer_pos -= viewport.min.as_vec2();
|
||||
}
|
||||
pointer_pos_by_camera
|
||||
|
Loading…
Reference in New Issue
Block a user