bevy
bevy copied to clipboard
Gizmos always draw on 2d sprites, z value and depth_bias neither works
Bevy version
0.13.2
Content
I want gizmos lines draw behind 2d sprites. I tried Gizmos#line()
with big negative z value and tried to change GizmosConfig#depth_bias
to -1.0. Neither works.
And I tried Gizmos#line_2d()
with -1.0 GizmosConfig#depth_bias
, it not works too.
fn setup_gizmo_config(mut config_store: ResMut<GizmoConfigStore>) {
for (_, config, _) in config_store.iter_mut() {
config.depth_bias = -1.0;
config.line_width = 1.0;
}
}
gizmos.line(start1, end1, color);
gizmos.line(start2, end2, color);
I took a little peek at this.
I ran into the same issue originally, but then noticed Gizmos.line_2d
exists, which takes the start and end points as a Vec2
(eg. no z value).
I also noted that the docs for depth_bias
state:
In 2D this setting has no effect and is effectively always -1.
Which leads me to believe that neither a z-value or depth bias will allow you to draw a gizmo behind a sprite.
After a bit of digging, I found out that you can draw a gizmo behind a sprite if you setup render_layers
appropriately in the GizmoConfig
and camera entities.
Here's a quick example:
use bevy::{prelude::*, render::view::RenderLayers};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (set_config, gizmos).chain())
.run();
}
fn setup(mut commands: Commands) {
// "Bottom" camera
let mut camera1 = Camera2dBundle::default();
camera1.camera.order = 1;
camera1.projection.scale = 0.1;
commands.spawn((camera1, RenderLayers::layer(1)));
// "Top" camera
let mut camera2 = Camera2dBundle::default();
camera2.camera.order = 2;
camera2.projection.scale = 0.1;
commands.spawn((camera2, RenderLayers::layer(2)));
commands.spawn((
SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::splat(100.0)),
..default()
},
transform: Transform::from_xyz(0.0, 0.0, 10.0),
..default()
},
RenderLayers::layer(2),
));
}
fn gizmos(mut gizmos: Gizmos) {
gizmos.line_2d(Vec2::new(-25.0, 25.0), Vec2::new(25.0, 25.0), Color::RED);
gizmos.line_2d(Vec2::new(0.0, 0.0), Vec2::new(0.0, 50.0), Color::YELLOW);
}
fn set_config(mut config_store: ResMut<GizmoConfigStore>) {
let (config, _) = config_store.config_mut::<DefaultGizmoConfigGroup>();
// Use the render layer of the "bottom" camera
config.render_layers = RenderLayers::layer(1);
}
Here, the gizmos are rendered behind the sprite. If you tweak the line in set_config
, you can move the gizmos back in front of the sprite by using the render layer that is "on top".
config.render_layers = RenderLayers::layer(2);
Some of the confusion might possibly come from the fact that 2D Gizmo methods are named as such, while most of the 3D methods don't have the _3d
suffix?
It works, thank you!
Do we need a better method to do that? I think using z axis value to decide 2d gizmos' occlusion relationship is more intuitive.