Migrate visibility to required components (#15474)

# Objective

The next step in the migration to required components: Deprecate
`VisibilityBundle` and make `Visibility` require `InheritedVisibility`
and `ViewVisibility`, as per the [chosen
proposal](https://hackmd.io/@bevy/required_components/%2FcO7JPSAQR5G0J_j5wNwtOQ).

## Solution

Deprecate `VisibilityBundle` and make `Visibility` require
`InheritedVisibility` and `ViewVisibility`.

I chose not to deprecate `SpatialBundle` yet, as doing so would mean
that we need to manually add `Visibility` to a bunch of places. It will
be nicer once meshes, sprites, lights, fog, and cameras have been
migrated, since they will require `Transform` and `Visibility` and
therefore not need manually added defaults for them.

---

## Migration Guide

Replace all insertions of `VisibilityBundle` with the `Visibility`
component. The other components required by it will now be inserted
automatically.
This commit is contained in:
Joona Aalto 2024-09-27 22:06:16 +03:00 committed by GitHub
parent 2486343e87
commit 39d6a745d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 41 additions and 46 deletions

View File

@ -43,6 +43,7 @@ pub mod view;
/// The render prelude. /// The render prelude.
/// ///
/// This includes the most common types in this crate, re-exported for your convenience. /// This includes the most common types in this crate, re-exported for your convenience.
#[expect(deprecated)]
pub mod prelude { pub mod prelude {
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{

View File

@ -1,3 +1,5 @@
#![expect(deprecated)]
mod range; mod range;
mod render_layers; mod render_layers;
@ -32,6 +34,7 @@ use super::NoCpuCulling;
/// `Visibility` to set the values of each entity's [`InheritedVisibility`] component. /// `Visibility` to set the values of each entity's [`InheritedVisibility`] component.
#[derive(Component, Clone, Copy, Reflect, Debug, PartialEq, Eq, Default)] #[derive(Component, Clone, Copy, Reflect, Debug, PartialEq, Eq, Default)]
#[reflect(Component, Default, Debug, PartialEq)] #[reflect(Component, Default, Debug, PartialEq)]
#[require(InheritedVisibility, ViewVisibility)]
pub enum Visibility { pub enum Visibility {
/// An entity with `Visibility::Inherited` will inherit the Visibility of its [`Parent`]. /// An entity with `Visibility::Inherited` will inherit the Visibility of its [`Parent`].
/// ///
@ -171,8 +174,13 @@ impl ViewVisibility {
/// * To show or hide an entity, you should set its [`Visibility`]. /// * To show or hide an entity, you should set its [`Visibility`].
/// * To get the inherited visibility of an entity, you should get its [`InheritedVisibility`]. /// * To get the inherited visibility of an entity, you should get its [`InheritedVisibility`].
/// * For visibility hierarchies to work correctly, you must have both all of [`Visibility`], [`InheritedVisibility`], and [`ViewVisibility`]. /// * For visibility hierarchies to work correctly, you must have both all of [`Visibility`], [`InheritedVisibility`], and [`ViewVisibility`].
/// * You may use the [`VisibilityBundle`] to guarantee this. /// * ~~You may use the [`VisibilityBundle`] to guarantee this.~~ [`VisibilityBundle`] is now deprecated.
/// [`InheritedVisibility`] and [`ViewVisibility`] are automatically inserted whenever [`Visibility`] is inserted.
#[derive(Bundle, Debug, Clone, Default)] #[derive(Bundle, Debug, Clone, Default)]
#[deprecated(
since = "0.15.0",
note = "Use the `Visibility` component instead. Inserting it will now also insert `InheritedVisibility` and `ViewVisibility` automatically."
)]
pub struct VisibilityBundle { pub struct VisibilityBundle {
/// The visibility of the entity. /// The visibility of the entity.
pub visibility: Visibility, pub visibility: Visibility,
@ -538,29 +546,16 @@ mod test {
use bevy_app::prelude::*; use bevy_app::prelude::*;
use bevy_hierarchy::BuildChildren; use bevy_hierarchy::BuildChildren;
fn visibility_bundle(visibility: Visibility) -> VisibilityBundle {
VisibilityBundle {
visibility,
..Default::default()
}
}
#[test] #[test]
fn visibility_propagation() { fn visibility_propagation() {
let mut app = App::new(); let mut app = App::new();
app.add_systems(Update, visibility_propagate_system); app.add_systems(Update, visibility_propagate_system);
let root1 = app let root1 = app.world_mut().spawn(Visibility::Hidden).id();
.world_mut() let root1_child1 = app.world_mut().spawn(Visibility::default()).id();
.spawn(visibility_bundle(Visibility::Hidden)) let root1_child2 = app.world_mut().spawn(Visibility::Hidden).id();
.id(); let root1_child1_grandchild1 = app.world_mut().spawn(Visibility::default()).id();
let root1_child1 = app.world_mut().spawn(VisibilityBundle::default()).id(); let root1_child2_grandchild1 = app.world_mut().spawn(Visibility::default()).id();
let root1_child2 = app
.world_mut()
.spawn(visibility_bundle(Visibility::Hidden))
.id();
let root1_child1_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id();
let root1_child2_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id();
app.world_mut() app.world_mut()
.entity_mut(root1) .entity_mut(root1)
@ -572,14 +567,11 @@ mod test {
.entity_mut(root1_child2) .entity_mut(root1_child2)
.add_children(&[root1_child2_grandchild1]); .add_children(&[root1_child2_grandchild1]);
let root2 = app.world_mut().spawn(VisibilityBundle::default()).id(); let root2 = app.world_mut().spawn(Visibility::default()).id();
let root2_child1 = app.world_mut().spawn(VisibilityBundle::default()).id(); let root2_child1 = app.world_mut().spawn(Visibility::default()).id();
let root2_child2 = app let root2_child2 = app.world_mut().spawn(Visibility::Hidden).id();
.world_mut() let root2_child1_grandchild1 = app.world_mut().spawn(Visibility::default()).id();
.spawn(visibility_bundle(Visibility::Hidden)) let root2_child2_grandchild1 = app.world_mut().spawn(Visibility::default()).id();
.id();
let root2_child1_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id();
let root2_child2_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id();
app.world_mut() app.world_mut()
.entity_mut(root2) .entity_mut(root2)
@ -650,14 +642,14 @@ mod test {
let mut app = App::new(); let mut app = App::new();
app.add_systems(Update, visibility_propagate_system); app.add_systems(Update, visibility_propagate_system);
let root1 = app.world_mut().spawn(visibility_bundle(Visible)).id(); let root1 = app.world_mut().spawn(Visible).id();
let root1_child1 = app.world_mut().spawn(visibility_bundle(Inherited)).id(); let root1_child1 = app.world_mut().spawn(Inherited).id();
let root1_child2 = app.world_mut().spawn(visibility_bundle(Hidden)).id(); let root1_child2 = app.world_mut().spawn(Hidden).id();
let root1_child1_grandchild1 = app.world_mut().spawn(visibility_bundle(Visible)).id(); let root1_child1_grandchild1 = app.world_mut().spawn(Visible).id();
let root1_child2_grandchild1 = app.world_mut().spawn(visibility_bundle(Visible)).id(); let root1_child2_grandchild1 = app.world_mut().spawn(Visible).id();
let root2 = app.world_mut().spawn(visibility_bundle(Inherited)).id(); let root2 = app.world_mut().spawn(Inherited).id();
let root3 = app.world_mut().spawn(visibility_bundle(Hidden)).id(); let root3 = app.world_mut().spawn(Hidden).id();
app.world_mut() app.world_mut()
.entity_mut(root1) .entity_mut(root1)
@ -710,15 +702,15 @@ mod test {
// Set up an entity hierarchy. // Set up an entity hierarchy.
let id1 = world.spawn(VisibilityBundle::default()).id(); let id1 = world.spawn(Visibility::default()).id();
let id2 = world.spawn(VisibilityBundle::default()).id(); let id2 = world.spawn(Visibility::default()).id();
world.entity_mut(id1).add_children(&[id2]); world.entity_mut(id1).add_children(&[id2]);
let id3 = world.spawn(visibility_bundle(Visibility::Hidden)).id(); let id3 = world.spawn(Visibility::Hidden).id();
world.entity_mut(id2).add_children(&[id3]); world.entity_mut(id2).add_children(&[id3]);
let id4 = world.spawn(VisibilityBundle::default()).id(); let id4 = world.spawn(Visibility::default()).id();
world.entity_mut(id3).add_children(&[id4]); world.entity_mut(id3).add_children(&[id4]);
// Test the hierarchy. // Test the hierarchy.
@ -785,7 +777,7 @@ mod test {
schedule.add_systems(visibility_propagate_system); schedule.add_systems(visibility_propagate_system);
let parent = world.spawn(()).id(); let parent = world.spawn(()).id();
let child = world.spawn(VisibilityBundle::default()).id(); let child = world.spawn(Visibility::default()).id();
world.entity_mut(parent).add_children(&[child]); world.entity_mut(parent).add_children(&[child]);
schedule.run(&mut world); schedule.run(&mut world);

View File

@ -9,7 +9,9 @@ use crate::prelude::{GlobalTransform, Transform};
/// * To place or move an entity, you should set its [`Transform`]. /// * To place or move an entity, you should set its [`Transform`].
/// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * To get the global transform of an entity, you should get its [`GlobalTransform`].
/// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`]. /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
/// * You may use the [`TransformBundle`] to guarantee this. /// * ~You may use the [`TransformBundle`] to guarantee this.~
/// [`TransformBundle`] is now deprecated.
/// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted.
/// ///
/// ## [`Transform`] and [`GlobalTransform`] /// ## [`Transform`] and [`GlobalTransform`]
/// ///

View File

@ -17,8 +17,8 @@ use {
/// ///
/// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * To get the global transform of an entity, you should get its [`GlobalTransform`].
/// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`]. /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ /// * ~You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~
/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. /// [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated.
/// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted. /// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted.
/// ///
/// ## [`Transform`] and [`GlobalTransform`] /// ## [`Transform`] and [`GlobalTransform`]

View File

@ -13,9 +13,9 @@ use {
/// * To place or move an entity, you should set its [`Transform`]. /// * To place or move an entity, you should set its [`Transform`].
/// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * To get the global transform of an entity, you should get its [`GlobalTransform`].
/// * To be displayed, an entity must have both a [`Transform`] and a [`GlobalTransform`]. /// * To be displayed, an entity must have both a [`Transform`] and a [`GlobalTransform`].
/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ /// * ~You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~
/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. /// [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated.
/// [`GlobalTransform`] is inserted automatically whenever [`Transform`] is inserted. /// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted.
/// ///
/// ## [`Transform`] and [`GlobalTransform`] /// ## [`Transform`] and [`GlobalTransform`]
/// ///

View File

@ -112,7 +112,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
}, },
Sprite::default(), Sprite::default(),
Transform::default(), Transform::default(),
VisibilityBundle::default(), Visibility::default(),
)); ));
} }