diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 6418f69ff8..a3b03238f8 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -2246,6 +2246,11 @@ pub struct CalculatedClip { pub clip: Rect, } +/// UI node entities with this component will ignore any clipping rect they inherit, +/// the node will not be clipped regardless of its ancestors' `Overflow` setting. +#[derive(Component)] +pub struct OverrideClip; + /// Indicates that this [`Node`] entity's front-to-back ordering is not controlled solely /// by its location in the UI hierarchy. A node with a higher z-index will appear on top /// of sibling nodes with a lower z-index. diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index c0e9d09d7b..0053e5a406 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -3,8 +3,8 @@ use crate::{ experimental::{UiChildren, UiRootNodes}, ui_transform::UiGlobalTransform, - CalculatedClip, ComputedNodeTarget, DefaultUiCamera, Display, Node, OverflowAxis, UiScale, - UiTargetCamera, + CalculatedClip, ComputedNodeTarget, DefaultUiCamera, Display, Node, OverflowAxis, OverrideClip, + UiScale, UiTargetCamera, }; use super::ComputedNode; @@ -12,7 +12,7 @@ use bevy_ecs::{ change_detection::DetectChangesMut, entity::Entity, hierarchy::ChildOf, - query::{Changed, With}, + query::{Changed, Has, With}, system::{Commands, Query, Res}, }; use bevy_math::{Rect, UVec2}; @@ -28,6 +28,7 @@ pub fn update_clipping_system( &ComputedNode, &UiGlobalTransform, Option<&mut CalculatedClip>, + Has, )>, ui_children: UiChildren, ) { @@ -50,15 +51,22 @@ fn update_clipping( &ComputedNode, &UiGlobalTransform, Option<&mut CalculatedClip>, + Has, )>, entity: Entity, mut maybe_inherited_clip: Option, ) { - let Ok((node, computed_node, transform, maybe_calculated_clip)) = node_query.get_mut(entity) + let Ok((node, computed_node, transform, maybe_calculated_clip, has_override_clip)) = + node_query.get_mut(entity) else { return; }; + // If the UI node entity has an `OverrideClip` component, discard any inherited clip rect + if has_override_clip { + maybe_inherited_clip = None; + } + // If `display` is None, clip the entire node and all its descendants by replacing the inherited clip with a default rect (which is empty) if node.display == Display::None { maybe_inherited_clip = Some(Rect::default());