Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable camera on window close #8802

Merged
merged 2 commits into from
Jun 10, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use bevy_reflect::FromReflect;
use bevy_transform::components::GlobalTransform;
use bevy_utils::{HashMap, HashSet};
use bevy_window::{
NormalizedWindowRef, PrimaryWindow, Window, WindowCreated, WindowRef, WindowResized,
NormalizedWindowRef, PrimaryWindow, Window, WindowClosed, WindowCreated, WindowRef,
WindowResized,
};

use std::{borrow::Cow, ops::Range};
Expand Down Expand Up @@ -492,6 +493,9 @@ impl NormalizedRenderTarget {

/// System in charge of updating a [`Camera`] when its window or projection changes.
///
/// The system will detect when a [`Window`] is closed and it disables any [`Camera`] that used that
/// [`Window`] has a [`RenderTarget`].
///
/// The system detects window creation and resize events to update the camera projection if
/// needed. It also queries any [`CameraProjection`] component associated with the same entity
/// as the [`Camera`] one, to automatically update the camera projection matrix.
Expand All @@ -509,9 +513,11 @@ impl NormalizedRenderTarget {
/// [`OrthographicProjection`]: crate::camera::OrthographicProjection
/// [`PerspectiveProjection`]: crate::camera::PerspectiveProjection
/// [`Projection`]: crate::camera::Projection
#[allow(clippy::too_many_arguments)]
pub fn camera_system<T: CameraProjection + Component>(
mut window_resized_events: EventReader<WindowResized>,
mut window_created_events: EventReader<WindowCreated>,
mut window_close_events: EventReader<WindowClosed>,
mut image_asset_events: EventReader<AssetEvent<Image>>,
primary_window: Query<Entity, With<PrimaryWindow>>,
windows: Query<(Entity, &Window)>,
Expand All @@ -520,6 +526,18 @@ pub fn camera_system<T: CameraProjection + Component>(
) {
let primary_window = primary_window.iter().next();

// Disable the camera associated to a window that's just been closed
for ev in window_close_events.iter() {
for (mut camera, _) in &mut cameras {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use query.get_mut here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be multiple camera per window, like for split screen. Also, the window doesn't have a camera entity id. It's the camera that contains a reference to the window.

let Some(NormalizedRenderTarget::Window(window_ref)) = camera.target.normalize(primary_window)
else { continue; };

if window_ref.entity() == ev.window {
camera.is_active = false;
}
}
}

let mut changed_window_ids = HashSet::new();
changed_window_ids.extend(window_created_events.iter().map(|event| event.window));
changed_window_ids.extend(window_resized_events.iter().map(|event| event.window));
Expand Down