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:📷: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>
This commit is contained in:
parent
38058965ef
commit
169254b938
@ -145,13 +145,15 @@ fn sprite_picking(
|
||||
continue;
|
||||
};
|
||||
|
||||
let viewport_pos = camera
|
||||
.logical_viewport_rect()
|
||||
.map(|v| v.min)
|
||||
.unwrap_or_default();
|
||||
let pos_in_viewport = location.position - viewport_pos;
|
||||
let viewport_pos = location.position;
|
||||
if let Some(viewport) = camera.logical_viewport_rect() {
|
||||
if !viewport.contains(viewport_pos) {
|
||||
// The pointer is outside the viewport, skip it
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let Ok(cursor_ray_world) = camera.viewport_to_world(cam_transform, pos_in_viewport) else {
|
||||
let Ok(cursor_ray_world) = camera.viewport_to_world(cam_transform, viewport_pos) else {
|
||||
continue;
|
||||
};
|
||||
let cursor_ray_len = cam_ortho.far - cam_ortho.near;
|
||||
|
Loading…
Reference in New Issue
Block a user