Skip to content

Commit 169254b

Browse files
authored
Fix sprite picking viewport (#19747)
# Objective Fixes sprite picking when using a viewport. Related to #19744. ## Solution - Do not substract `viewport.min` as `Camera::viewport_to_world` already does that. - Skip pointers outside the viewport. ## Testing Tested with the following example: <details> <summary>Click to expand code</summary> ```rust use bevy::{ prelude::*, render::camera::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(( Transform::from_xyz(100.0, 100.0, 0.0), Sprite::from_color(Color::srgb(0.0, 1.0, 0.0), Vec2::new(200.0, 200.0)), Pickable::default(), )) .observe( |trigger: On<Pointer<Drag>>, mut transform: Query<&mut Transform>| { let mut transform = transform.get_mut(trigger.target()).unwrap(); transform.translation.x += trigger.delta.x; transform.translation.y -= 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>(); }, ); } ``` </details>
1 parent 3805896 commit 169254b

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

crates/bevy_sprite/src/picking_backend.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,15 @@ fn sprite_picking(
145145
continue;
146146
};
147147

148-
let viewport_pos = camera
149-
.logical_viewport_rect()
150-
.map(|v| v.min)
151-
.unwrap_or_default();
152-
let pos_in_viewport = location.position - viewport_pos;
148+
let viewport_pos = location.position;
149+
if let Some(viewport) = camera.logical_viewport_rect() {
150+
if !viewport.contains(viewport_pos) {
151+
// The pointer is outside the viewport, skip it
152+
continue;
153+
}
154+
}
153155

154-
let Ok(cursor_ray_world) = camera.viewport_to_world(cam_transform, pos_in_viewport) else {
156+
let Ok(cursor_ray_world) = camera.viewport_to_world(cam_transform, viewport_pos) else {
155157
continue;
156158
};
157159
let cursor_ray_len = cam_ortho.far - cam_ortho.near;

0 commit comments

Comments
 (0)