Bevy Version: | 0.9 | (outdated!) |
---|
Visibility
Relevant official examples:
parenting
.
Visibility is used to control if something is to be rendered or not. If you want an entity to exist in the world, just not be displayed, you can hide it.
/// Prepare the game map, but do not display it until later
fn setup_map_hidden(
mut commands: Commands,
) {
commands.spawn((
GameMapEntity,
SceneBundle {
scene: todo!(),
visibility: Visibility {
is_visible: false,
},
..Default::default()
},
));
}
/// When everything is ready, un-hide the game map
fn reveal_map(
mut query: Query<&mut Visibility, With<GameMapEntity>>,
) {
let mut vis_map = query.single_mut();
vis_map.is_visible = true;
}
Visibility Components
In Bevy, visibility is represented by two components:
Visibility
and ComputedVisibility
.
Any Entity that represents an object in the game world needs to have both. All of Bevy's built-in bundle types include them.
If you are creating a custom entity without using those bundles, you can use one of the following to ensure you don't miss them:
SpatialBundle
for transforms + visibilityVisibilityBundle
for just visibility
fn spawn_special_entity(
mut commands: Commands,
) {
// create an entity that does not use one of the common Bevy bundles,
// but still needs transforms and visibility
commands.spawn((
ComponentA,
ComponentB,
SpatialBundle {
transform: Transform::from_scale(Vec3::splat(3.0)),
visibility: Visibility {
is_visible: false,
},
..Default::default()
},
));
}
Visibility
Visibility
is the "user-facing toggle". This is where
you specify if you want this entity to be visible or not.
If you hide an entity that has children, they will also be
hidden, regardless of what their individual Visibility
value is set to.
ComputedVisibility
ComputedVisibility
represents the actual final
decision made by Bevy about whether this entity needs to be displayed.
The value of ComputedVisibility
is read-only. It
is managed internally by Bevy.
It can be affected by the visibility of parent entities, if any.
It is also affected by "culling" systems. If the entity is not in the range of any Camera or Light, it does not need to be rendered, so Bevy will hide it.
Checking Actual Visibility
You can use ComputedVisibility
to check if
the entity is actually visible.
Bevy's internal visibility computations are done in the
PostUpdate
stage. To get the up-to-date
values for the current frame, your system must be ordered
after these bevy-internal systems. You can use the
VisibilitySystems
labels.
/// Check if the Player was hidden manually
fn debug_player_visibility(
query: Query<&ComputedVisibility, With<Player>>,
) {
let vis = query.single();
// check if it was manually hidden via Visibility
// (incl. by any parent entity)
debug!("Player visible due to hierachy: {:?}", vis.is_visible_in_hierarchy());
}
/// Check if balloons are seen by any Camera, Light, etc… (not culled)
fn debug_balloon_visibility(
query: Query<&ComputedVisibility, With<Balloon>>,
) {
for vis in query.iter() {
debug!("Balloon is in view: {:?}", vis.is_visible_in_view());
// check overall final actual visibility
// (combines visible-in-hierarchy and visible-in-view)
debug!("Balloon is visible: {:?}", vis.is_visible());
}
}
fn main() {
// the labels to use for ordering
use bevy::render::view::VisibilitySystems;
App::new()
.add_plugins(DefaultPlugins)
.add_system_to_stage(
CoreStage::PostUpdate,
debug_balloon_visibility
// in-view visibility (culling) is done here:
.after(VisibilitySystems::CheckVisibility)
)
.add_system_to_stage(
CoreStage::PostUpdate,
debug_player_visibility
// hierarchy propagation is done here:
.after(VisibilitySystems::VisibilityPropagate)
)
.run();
}