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.
This commit is contained in:
davier 2021-12-24 07:10:12 +00:00
parent adb3ad399c
commit 76ec709ede
3 changed files with 19 additions and 5 deletions

View file

@ -15,7 +15,7 @@ use crate::{
}; };
/// User indication of whether an entity is visible /// User indication of whether an entity is visible
#[derive(Component, Clone, Reflect)] #[derive(Component, Clone, Reflect, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub struct Visibility { pub struct Visibility {
pub is_visible: bool, pub is_visible: bool,

View file

@ -5,7 +5,7 @@ use crate::{
use bevy_ecs::bundle::Bundle; use bevy_ecs::bundle::Bundle;
use bevy_render::{ use bevy_render::{
camera::{Camera, DepthCalculation, OrthographicProjection, WindowOrigin}, camera::{Camera, DepthCalculation, OrthographicProjection, WindowOrigin},
view::VisibleEntities, view::{Visibility, VisibleEntities},
}; };
use bevy_text::Text; use bevy_text::Text;
use bevy_transform::prelude::{GlobalTransform, Transform}; use bevy_transform::prelude::{GlobalTransform, Transform};
@ -18,6 +18,7 @@ pub struct NodeBundle {
pub image: UiImage, pub image: UiImage,
pub transform: Transform, pub transform: Transform,
pub global_transform: GlobalTransform, pub global_transform: GlobalTransform,
pub visibility: Visibility,
} }
#[derive(Bundle, Clone, Debug, Default)] #[derive(Bundle, Clone, Debug, Default)]
@ -30,6 +31,7 @@ pub struct ImageBundle {
pub image: UiImage, pub image: UiImage,
pub transform: Transform, pub transform: Transform,
pub global_transform: GlobalTransform, pub global_transform: GlobalTransform,
pub visibility: Visibility,
} }
#[derive(Bundle, Clone, Debug)] #[derive(Bundle, Clone, Debug)]
@ -41,6 +43,7 @@ pub struct TextBundle {
pub focus_policy: FocusPolicy, pub focus_policy: FocusPolicy,
pub transform: Transform, pub transform: Transform,
pub global_transform: GlobalTransform, pub global_transform: GlobalTransform,
pub visibility: Visibility,
} }
impl Default for TextBundle { impl Default for TextBundle {
@ -53,6 +56,7 @@ impl Default for TextBundle {
style: Default::default(), style: Default::default(),
transform: Default::default(), transform: Default::default(),
global_transform: Default::default(), global_transform: Default::default(),
visibility: Default::default(),
} }
} }
} }
@ -68,6 +72,7 @@ pub struct ButtonBundle {
pub image: UiImage, pub image: UiImage,
pub transform: Transform, pub transform: Transform,
pub global_transform: GlobalTransform, pub global_transform: GlobalTransform,
pub visibility: Visibility,
} }
impl Default for ButtonBundle { impl Default for ButtonBundle {
@ -82,6 +87,7 @@ impl Default for ButtonBundle {
image: Default::default(), image: Default::default(),
transform: Default::default(), transform: Default::default(),
global_transform: Default::default(), global_transform: Default::default(),
visibility: Default::default(),
} }
} }
} }

View file

@ -23,7 +23,7 @@ use bevy_render::{
render_resource::*, render_resource::*,
renderer::{RenderDevice, RenderQueue}, renderer::{RenderDevice, RenderQueue},
texture::Image, texture::Image,
view::ViewUniforms, view::{ViewUniforms, Visibility},
RenderApp, RenderStage, RenderWorld, RenderApp, RenderStage, RenderWorld,
}; };
use bevy_sprite::{Rect, SpriteAssetEvents, TextureAtlas}; use bevy_sprite::{Rect, SpriteAssetEvents, TextureAtlas};
@ -139,12 +139,16 @@ pub fn extract_uinodes(
&GlobalTransform, &GlobalTransform,
&UiColor, &UiColor,
&UiImage, &UiImage,
&Visibility,
Option<&CalculatedClip>, Option<&CalculatedClip>,
)>, )>,
) { ) {
let mut extracted_uinodes = render_world.get_resource_mut::<ExtractedUiNodes>().unwrap(); let mut extracted_uinodes = render_world.get_resource_mut::<ExtractedUiNodes>().unwrap();
extracted_uinodes.uinodes.clear(); 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(); let image = image.0.clone_weak();
// Skip loading images // Skip loading images
if !images.contains(image.clone_weak()) { if !images.contains(image.clone_weak()) {
@ -174,6 +178,7 @@ pub fn extract_text_uinodes(
&Node, &Node,
&GlobalTransform, &GlobalTransform,
&Text, &Text,
&Visibility,
Option<&CalculatedClip>, Option<&CalculatedClip>,
)>, )>,
) { ) {
@ -185,7 +190,10 @@ pub fn extract_text_uinodes(
1. 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`) // Skip if size is set to zero (e.g. when a parent is set to `Display::None`)
if uinode.size == Vec2::ZERO { if uinode.size == Vec2::ZERO {
continue; continue;