diff --git a/crates/bevy_ui/src/auto_directional_navigation.rs b/crates/bevy_ui/src/auto_directional_navigation.rs index d714c3b3c5fda..4c215d3dac089 100644 --- a/crates/bevy_ui/src/auto_directional_navigation.rs +++ b/crates/bevy_ui/src/auto_directional_navigation.rs @@ -6,7 +6,7 @@ use crate::{ComputedNode, ComputedUiTargetCamera, UiGlobalTransform}; use bevy_camera::visibility::InheritedVisibility; use bevy_ecs::{prelude::*, system::SystemParam}; -use bevy_math::CompassOctant; +use bevy_math::{ops, CompassOctant, Vec2}; use bevy_input_focus::{ directional_navigation::{ @@ -184,12 +184,13 @@ impl<'w, 's> AutoDirectionalNavigator<'w, 's> { if let Some(tc) = computed_target_camera.get() && tc == target_camera { - let (_scale, _rotation, translation) = - transform.to_scale_angle_translation(); + let (scale, rotation, translation) = transform.to_scale_angle_translation(); + let scaled_size = computed.size() * computed.inverse_scale_factor() * scale; + let rotated_size = get_rotated_bounds(scaled_size, rotation); Some(FocusableArea { entity, position: translation * computed.inverse_scale_factor(), - size: computed.size() * computed.inverse_scale_factor(), + size: rotated_size, }) } else { // The node either does not have a target camera or it is not the same as the desired one. @@ -212,13 +213,15 @@ impl<'w, 's> AutoDirectionalNavigator<'w, 's> { None, |(entity, computed_target_camera, computed, transform)| { if let Some(target_camera) = computed_target_camera.get() { - let (_scale, _rotation, translation) = transform.to_scale_angle_translation(); + let (scale, rotation, translation) = transform.to_scale_angle_translation(); + let scaled_size = computed.size() * computed.inverse_scale_factor() * scale; + let rotated_size = get_rotated_bounds(scaled_size, rotation); Some(( target_camera, FocusableArea { entity, position: translation * computed.inverse_scale_factor(), - size: computed.size() * computed.inverse_scale_factor(), + size: rotated_size, }, )) } else { @@ -228,3 +231,15 @@ impl<'w, 's> AutoDirectionalNavigator<'w, 's> { ) } } + +fn get_rotated_bounds(size: Vec2, rotation: f32) -> Vec2 { + if rotation == 0.0 { + return size; + } + let cos_r = ops::cos(rotation).abs(); + let sin_r = ops::sin(rotation).abs(); + Vec2::new( + size.x * cos_r + size.y * sin_r, + size.x * sin_r + size.y * cos_r, + ) +} diff --git a/examples/ui/auto_directional_navigation.rs b/examples/ui/auto_directional_navigation.rs index fe5fda3fa9982..4bd63946f6f44 100644 --- a/examples/ui/auto_directional_navigation.rs +++ b/examples/ui/auto_directional_navigation.rs @@ -20,7 +20,7 @@ use bevy::{ directional_navigation::{AutoNavigationConfig, DirectionalNavigationPlugin}, InputDispatchPlugin, InputFocus, InputFocusVisible, }, - math::{CompassOctant, Dir2}, + math::{CompassOctant, Dir2, Rot2}, picking::{ backend::HitData, pointer::{Location, PointerId}, @@ -210,6 +210,15 @@ fn setup_scattered_ui(mut commands: Commands, mut input_focus: ResMut