Skip to content

Commit 3072955

Browse files
committed
Make the ui cam extract system immutable
Following #4402, it is now impossible to mutate the main world from the render world, so we split the update to the projection into a different system ran in the main world.
1 parent 109a06d commit 3072955

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

crates/bevy_ui/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use bevy_ecs::schedule::{ParallelSystemDescriptorCoercion, SystemLabel};
3030
use bevy_input::InputSystem;
3131
use bevy_transform::TransformSystem;
3232
use bevy_window::ModifiesWindows;
33-
use update::{ui_z_system, update_clipping_system};
33+
use update::{ui_z_system, update_clipping_system, update_ui_camera_perspective};
3434

3535
/// The basic plugin for Bevy UI
3636
#[derive(Default)]
@@ -43,6 +43,8 @@ pub enum UiSystem {
4343
Flex,
4444
/// After this label, input interactions with UI entities have been updated for this frame
4545
Focus,
46+
/// Update Ui camera perspective to fit new viewport logical size.
47+
UpdateUiCameraPerspective,
4648
}
4749

4850
impl Plugin for UiPlugin {
@@ -88,6 +90,10 @@ impl Plugin for UiPlugin {
8890
CoreStage::PostUpdate,
8991
widget::image_node_system.before(UiSystem::Flex),
9092
)
93+
.add_system_to_stage(
94+
CoreStage::Last,
95+
update_ui_camera_perspective.label(UiSystem::UpdateUiCameraPerspective),
96+
)
9197
.add_system_to_stage(
9298
CoreStage::PostUpdate,
9399
flex_node_system

crates/bevy_ui/src/render/mod.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -233,28 +233,19 @@ pub struct UiCamera {
233233

234234
pub fn extract_default_ui_camera_view<T: Component>(
235235
mut commands: Commands,
236-
mut query: Extract<Query<(Entity, &Camera, Option<&mut UiCameraConfig>), With<T>>>,
236+
query: Extract<Query<(Entity, &Camera, Option<&UiCameraConfig>), With<T>>>,
237237
) {
238-
for (camera_entity, camera, opt_ui_config) in query.iter_mut() {
239-
let ui_config = opt_ui_config.as_deref().cloned().unwrap_or_default();
238+
for (camera_entity, camera, opt_ui_config) in query.iter() {
239+
let ui_config = opt_ui_config.cloned().unwrap_or_default();
240240
// ignore cameras with disabled ui
241241
if !ui_config.show_ui {
242242
continue;
243243
}
244-
if let (Some(logical_size), Some(physical_size)) = (
245-
camera.logical_viewport_size(),
246-
camera.physical_viewport_size(),
247-
) {
248-
let mut projection = ui_config.projection.clone();
249-
projection.update(logical_size.x, logical_size.y);
250-
let projection_matrix = projection.get_projection_matrix();
251-
if let Some(mut config_to_update) = opt_ui_config {
252-
config_to_update.projection = projection;
253-
}
244+
if let Some(physical_size) = camera.physical_viewport_size() {
254245
let ui_camera = commands
255246
.spawn()
256247
.insert(ExtractedView {
257-
projection: projection_matrix,
248+
projection: ui_config.projection.get_projection_matrix(),
258249
transform: GlobalTransform::from_xyz(
259250
ui_config.position.x,
260251
ui_config.position.y,

crates/bevy_ui/src/update.rs

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

55
use super::Node;
66
use bevy_ecs::{
77
entity::Entity,
8+
prelude::{Changed, Or},
89
query::{With, Without},
910
system::{Commands, Query},
1011
};
1112
use bevy_hierarchy::{Children, Parent};
1213
use bevy_math::Vec2;
14+
use bevy_render::camera::{Camera, CameraProjection};
1315
use bevy_sprite::Rect;
1416
use bevy_transform::components::{GlobalTransform, Transform};
1517

@@ -82,6 +84,19 @@ pub fn update_clipping_system(
8284
}
8385
}
8486

87+
pub fn update_ui_camera_perspective(
88+
mut query: Query<
89+
(&Camera, &mut UiCameraConfig),
90+
Or<(Changed<Camera>, Changed<UiCameraConfig>)>,
91+
>,
92+
) {
93+
for (camera, mut ui_config) in query.iter_mut() {
94+
if let Some(logical_size) = camera.logical_viewport_size() {
95+
ui_config.projection.update(logical_size.x, logical_size.y);
96+
}
97+
}
98+
}
99+
85100
fn update_clipping(
86101
commands: &mut Commands,
87102
children_query: &Query<&Children>,

0 commit comments

Comments
 (0)