Skip to content

Commit 17153b6

Browse files
committed
Update Node ComputedVisibility based on UI RenderLayers
1 parent d5ee6b4 commit 17153b6

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

crates/bevy_ui/src/entity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ pub struct ButtonBundle {
177177
/// it will display the UI by default.
178178
///
179179
/// [`Camera`]: bevy_render::camera::Camera
180-
#[derive(Component, Clone)]
180+
#[derive(Component, Debug, Clone)]
181181
pub struct UiCameraConfig {
182182
/// Whether to output UI to this camera view.
183183
///

crates/bevy_ui/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ pub mod prelude {
2727
use bevy_app::prelude::*;
2828
use bevy_ecs::schedule::{ParallelSystemDescriptorCoercion, SystemLabel};
2929
use bevy_input::InputSystem;
30+
use bevy_render::view::VisibilitySystems;
3031
use bevy_transform::TransformSystem;
3132
use bevy_window::ModifiesWindows;
32-
use update::{ui_z_system, update_clipping_system};
33+
use update::{ui_z_system, update_clipping_system, update_layer_visibility};
3334

3435
/// The basic plugin for Bevy UI
3536
#[derive(Default)]
@@ -42,6 +43,11 @@ pub enum UiSystem {
4243
Flex,
4344
/// After this label, input interactions with UI entities have been updated for this frame
4445
Focus,
46+
/// Update the [`ComputedVisibility`] component of [`Node`] entities to reflect
47+
/// their visibility in accordance to UI cameras.
48+
///
49+
/// [`ComputedVisibility`]: bevy_render::view::ComputedVisibility
50+
LayerVisibility,
4551
}
4652

4753
impl Plugin for UiPlugin {
@@ -94,6 +100,12 @@ impl Plugin for UiPlugin {
94100
.before(TransformSystem::TransformPropagate)
95101
.after(ModifiesWindows),
96102
)
103+
.add_system_to_stage(
104+
CoreStage::PostUpdate,
105+
update_layer_visibility
106+
.label(UiSystem::LayerVisibility)
107+
.after(VisibilitySystems::CheckVisibility),
108+
)
97109
.add_system_to_stage(
98110
CoreStage::PostUpdate,
99111
ui_z_system

crates/bevy_ui/src/render/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ fn get_ui_graph(render_app: &mut App) -> RenderGraph {
158158
ui_graph
159159
}
160160

161+
#[derive(Debug)]
161162
pub struct ExtractedUiNode {
162163
pub transform: Mat4,
163164
pub color: Color,
@@ -224,9 +225,19 @@ const UI_CAMERA_FAR: f32 = 1000.0;
224225
// TODO: Evaluate if we still need this.
225226
const UI_CAMERA_TRANSFORM_OFFSET: f32 = -0.1;
226227

228+
/// The UI camera used by this Camera's viewport.
229+
///
230+
/// This component is inserted into the render world in the
231+
/// [`extract_default_ui_camera_view`] system.
232+
///
233+
/// The component is attached to the "actual" viewport's camera.
234+
/// The UI camera's `ExtractedView` is attached to the entity in the
235+
/// `entity` field.
227236
#[derive(Component, Debug)]
228237
pub struct UiCamera {
238+
/// The entity for the UI camera.
229239
pub entity: Entity,
240+
/// UI nodes layer this camera shows.
230241
layers: RenderLayers,
231242
}
232243

crates/bevy_ui/src/update.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This module contains systems that update the UI when something changes
22
3-
use crate::{CalculatedClip, Overflow, Style};
3+
use crate::{entity::UiCameraConfig, CalculatedClip, Overflow, Style};
44

55
use super::Node;
66
use bevy_ecs::{
@@ -10,6 +10,7 @@ use bevy_ecs::{
1010
};
1111
use bevy_hierarchy::{Children, Parent};
1212
use bevy_math::Vec2;
13+
use bevy_render::view::{ComputedVisibility, RenderLayers};
1314
use bevy_sprite::Rect;
1415
use bevy_transform::components::{GlobalTransform, Transform};
1516

@@ -64,6 +65,30 @@ fn update_hierarchy(
6465
current_global_z
6566
}
6667

68+
/// Correct the `ComputedVisibility` set by [`check_visibility`] for UI nodes.
69+
///
70+
/// Since [`check_visibility`] has no concept of UI cameras, we need a "post-pass"
71+
/// where we re-enable UI nodes that are visible because they have a matching
72+
/// UI camera in their layer.
73+
///
74+
/// [`check_visibility`]: bevy_render::view::visibility::check_visibility
75+
pub fn update_layer_visibility(
76+
ui_cams: Query<&UiCameraConfig>,
77+
mut nodes: Query<(&mut ComputedVisibility, &RenderLayers), With<Node>>,
78+
) {
79+
for config in &ui_cams {
80+
// Skip configs with default render layers, since `check_visibility` assumes it
81+
if config.ui_render_layers == RenderLayers::default() {
82+
continue;
83+
}
84+
for (mut visibility, node_layers) in &mut nodes {
85+
if config.ui_render_layers.intersects(node_layers) {
86+
visibility.set_visible_in_view();
87+
}
88+
}
89+
}
90+
}
91+
6792
/// Updates clipping for all nodes
6893
pub fn update_clipping_system(
6994
mut commands: Commands,

0 commit comments

Comments
 (0)