`DebugUiPlugin` does not handle node with custom transform correctly
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## Bevy version
main
## What you did
Example code, note that the second box has a transform.
```
commands.spawn(NodeBundle {
style: Style {
width: Val::Px(100.0),
height: Val::Px(100.0),
..default()
},
background_color: Color::WHITE.into(),
..default()
});
commands.spawn(NodeBundle {
style: Style {
width: Val::Px(100.0),
height: Val::Px(100.0),
..default()
},
transform: Transform::from_scale(Vec3::splat(2.)),
background_color: Color::WHITE.into(),
..default()
});
```
## What went wrong
The outline of the second box does not display correctly. It should be scaled with the box.
Here is how it should be

But on main, it like this

## Additional information
- This can be fixed by handling the transform when drawing the outline with the change below. ~~However, the real problem might be in the [ui_layout_system](https://github.com/bevyengine/bevy/blob/main/crates/bevy_ui/src/layout/mod.rs#L272) that it does not update the `Node.calculated_size` correctly~~
Code
```diff
--- a/crates/bevy_dev_tools/src/debug_overlay/mod.rs
+++ b/crates/bevy_dev_tools/src/debug_overlay/mod.rs
@@ -14,7 +14,7 @@ use bevy_render::{
prelude::*,
view::{RenderLayers, VisibilitySystems},
};
-use bevy_transform::{prelude::GlobalTransform, TransformSystem};
+use bevy_transform::{components::Transform, prelude::GlobalTransform, TransformSystem};
use bevy_ui::{DefaultUiCamera, Display, Node, Style, TargetCamera, UiScale};
use bevy_utils::{default, warn_once};
use bevy_window::{PrimaryWindow, Window, WindowRef};
@@ -37,10 +37,15 @@ struct LayoutRect {
}
impl LayoutRect {
- fn new(trans: &GlobalTransform, node: &Node, scale: f32) -> Self {
+ fn new(
+ global_transform: &GlobalTransform,
+ node: &Node,
+ node_transform: &Transform,
+ scale: f32,
+ ) -> Self {
let mut this = Self {
- pos: trans.translation().xy() * scale,
- size: node.size() * scale,
+ pos: global_transform.translation().xy() * scale,
+ size: node.size() * node_transform.scale.truncate() * scale,
};
this.pos -= this.size / 2.;
this
@@ -120,12 +125,18 @@ fn update_debug_camera(
}
/// The function that goes over every children of given [`Entity`], skipping the not visible ones and drawing the gizmos outlines.
-fn outline_nodes(outline: &OutlineParam, draw: &mut InsetGizmo, this_entity: Entity, scale: f32) {
+fn outline_nodes(
+ outline: &OutlineParam,
+ draw: &mut InsetGizmo,
+ this_entity: Entity,
+ node_transform: &Transform,
+ scale: f32,
+) {
let Ok(to_iter) = outline.children.get(this_entity) else {
return;
};
- for (entity, trans, node, style, children) in outline.nodes.iter_many(to_iter) {
+ for (entity, global_transform, node, style, children) in outline.nodes.iter_many(to_iter) {
if style.is_none() || style.is_some_and(|s| matches!(s.display, Display::None)) {
continue;
}
@@ -135,10 +146,10 @@ fn outline_nodes(outline: &OutlineParam, draw: &mut InsetGizmo, this_entity: Ent
continue;
}
}
- let rect = LayoutRect::new(trans, node, scale);
+ let rect = LayoutRect::new(global_transform, node, node_transform, scale);
outline_node(entity, rect, draw);
if children.is_some() {
- outline_nodes(outline, draw, entity, scale);
+ outline_nodes(outline, draw, entity, node_transform, scale);
}
draw.clear_scope(rect);
}
@@ -181,6 +192,7 @@ fn outline_roots(
Entity,
&GlobalTransform,
&Node,
+ &Transform,
Option<&ViewVisibility>,
Option<&TargetCamera>,
),
@@ -209,7 +221,9 @@ fn outline_roots(
.map_or(2., |(config, _)| config.line_width)
/ window_scale;
let mut draw = InsetGizmo::new(draw, cam.debug_camera, line_width);
- for (entity, trans, node, view_visibility, maybe_target_camera) in &roots {
+ for (entity, global_transform, node, node_transform, view_visibility, maybe_target_camera) in
+ &roots
+ {
if let Some(view_visibility) = view_visibility {
// If the entity isn't visible, we will not draw any lines.
if !view_visibility.get() {
@@ -240,9 +254,9 @@ fn outline_roots(
}
}
- let rect = LayoutRect::new(trans, node, scale_factor);
+ let rect = LayoutRect::new(global_transform, node, node_transform, scale_factor);
outline_node(entity, rect, &mut draw);
- outline_nodes(&outline, &mut draw, entity, scale_factor);
+ outline_nodes(&outline, &mut draw, entity, node_transform, scale_factor);
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.