From 76ec709edee77c28a4a027ff1ab8d768be523633 Mon Sep 17 00:00:00 2001 From: davier Date: Fri, 24 Dec 2021 07:10:12 +0000 Subject: [PATCH] Add Visibility component to UI (#3426) # Objective Fixes #3422 ## Solution Adds the existing `Visibility` component to UI bundles and checks for it in the extract phase of the render app. The `ComputedVisibility` component was not added. I don't think the UI camera needs frustum culling, but having `RenderLayers` work may be desirable. However I think we would need to change `check_visibility()` to differentiate between 2d, 3d and UI entities. --- crates/bevy_render/src/view/visibility/mod.rs | 2 +- crates/bevy_ui/src/entity.rs | 8 +++++++- crates/bevy_ui/src/render/mod.rs | 14 +++++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index 50924d06ae..d38e45231b 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -15,7 +15,7 @@ use crate::{ }; /// User indication of whether an entity is visible -#[derive(Component, Clone, Reflect)] +#[derive(Component, Clone, Reflect, Debug)] #[reflect(Component)] pub struct Visibility { pub is_visible: bool, diff --git a/crates/bevy_ui/src/entity.rs b/crates/bevy_ui/src/entity.rs index da8c307167..a65d594506 100644 --- a/crates/bevy_ui/src/entity.rs +++ b/crates/bevy_ui/src/entity.rs @@ -5,7 +5,7 @@ use crate::{ use bevy_ecs::bundle::Bundle; use bevy_render::{ camera::{Camera, DepthCalculation, OrthographicProjection, WindowOrigin}, - view::VisibleEntities, + view::{Visibility, VisibleEntities}, }; use bevy_text::Text; use bevy_transform::prelude::{GlobalTransform, Transform}; @@ -18,6 +18,7 @@ pub struct NodeBundle { pub image: UiImage, pub transform: Transform, pub global_transform: GlobalTransform, + pub visibility: Visibility, } #[derive(Bundle, Clone, Debug, Default)] @@ -30,6 +31,7 @@ pub struct ImageBundle { pub image: UiImage, pub transform: Transform, pub global_transform: GlobalTransform, + pub visibility: Visibility, } #[derive(Bundle, Clone, Debug)] @@ -41,6 +43,7 @@ pub struct TextBundle { pub focus_policy: FocusPolicy, pub transform: Transform, pub global_transform: GlobalTransform, + pub visibility: Visibility, } impl Default for TextBundle { @@ -53,6 +56,7 @@ impl Default for TextBundle { style: Default::default(), transform: Default::default(), global_transform: Default::default(), + visibility: Default::default(), } } } @@ -68,6 +72,7 @@ pub struct ButtonBundle { pub image: UiImage, pub transform: Transform, pub global_transform: GlobalTransform, + pub visibility: Visibility, } impl Default for ButtonBundle { @@ -82,6 +87,7 @@ impl Default for ButtonBundle { image: Default::default(), transform: Default::default(), global_transform: Default::default(), + visibility: Default::default(), } } } diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 5750becce9..46fe825a12 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -23,7 +23,7 @@ use bevy_render::{ render_resource::*, renderer::{RenderDevice, RenderQueue}, texture::Image, - view::ViewUniforms, + view::{ViewUniforms, Visibility}, RenderApp, RenderStage, RenderWorld, }; use bevy_sprite::{Rect, SpriteAssetEvents, TextureAtlas}; @@ -139,12 +139,16 @@ pub fn extract_uinodes( &GlobalTransform, &UiColor, &UiImage, + &Visibility, Option<&CalculatedClip>, )>, ) { let mut extracted_uinodes = render_world.get_resource_mut::().unwrap(); extracted_uinodes.uinodes.clear(); - for (uinode, transform, color, image, clip) in uinode_query.iter() { + for (uinode, transform, color, image, visibility, clip) in uinode_query.iter() { + if !visibility.is_visible { + continue; + } let image = image.0.clone_weak(); // Skip loading images if !images.contains(image.clone_weak()) { @@ -174,6 +178,7 @@ pub fn extract_text_uinodes( &Node, &GlobalTransform, &Text, + &Visibility, Option<&CalculatedClip>, )>, ) { @@ -185,7 +190,10 @@ pub fn extract_text_uinodes( 1. }; - for (entity, uinode, transform, text, clip) in uinode_query.iter() { + for (entity, uinode, transform, text, visibility, clip) in uinode_query.iter() { + if !visibility.is_visible { + continue; + } // Skip if size is set to zero (e.g. when a parent is set to `Display::None`) if uinode.size == Vec2::ZERO { continue;