Skip to content

Text2d Aabb aren't in the right place and can get culled when they shouldn't #20145

@ejrh

Description

@ejrh

Bevy version

0294fa8 (main @ 15th July '25)

What you did

Placing text with a large TextBounds, intending that the bounds shows the maximum size the text should take up, even though the current text is small and fits easily inside.

What went wrong

Text isn't rendered, because the computed Aabb is off screen and gets culled.

Additional information

Seems to be caused by this earlier fix: #17365

If I don't specify TextBounds, or I disable calculate_bounds_text2d, or the text is sized and located such that the Aabb is within the screen, then the text is rendered as expected.

I have updated the example from #17365 for current Bevy, also to show the text bounds and calculated Aabb's, which are way off where the text is.

Image

I tried fixing it by simply disregarding TextBounds in the Aabb computation, but I suspect that breaks what this previous change was trying to fix!

use bevy::prelude::*;
use bevy::color::palettes;
use bevy::sprite::Anchor;
use bevy::text::TextBounds;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn example(commands: &mut Commands, dest: Vec3, justify: Justify) {
    commands.spawn((
        Sprite::from_color(palettes::css::YELLOW, 10. * Vec2::ONE),
        Anchor::CENTER,
        Transform::from_translation(dest),
    ));

    for (a, bg) in [
        (Anchor::TOP_LEFT, palettes::css::DARK_SLATE_GREY),
        (Anchor::TOP_RIGHT, palettes::css::DARK_OLIVEGREEN),
        (Anchor::BOTTOM_RIGHT, palettes::css::DARK_SLATE_GREY),
        (Anchor::BOTTOM_LEFT, palettes::css::DARK_OLIVEGREEN),
    ] {
        commands.spawn((
            Sprite::from_color(bg, Vec2::new(300., 75.)),
            a,
            Transform::from_translation(dest - Vec3::Z),
        ));

        commands.spawn((
            Text2d(format!("L R\n{:?}\n{:?}", a.0, justify)),
            TextFont {
                font_size: 14.0,
                ..default()
            },
            TextLayout {
                justify,
                ..Default::default()
            },
            TextBounds::new(300., 75.),
            Transform::from_translation(dest + Vec3::Z),
            a,
            ShowAabbGizmo::default(),
        ));
    }
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d::default());

    for (i, j) in [
        Justify::Left,
        Justify::Right,
        Justify::Center,
        Justify::Justified,
    ]
        .into_iter()
        .enumerate()
    {
        example(&mut commands, (240. - 160. * i as f32) * Vec3::Y, j);
    }

    commands.spawn((
        Sprite::from_color(palettes::css::GREEN, 10. * Vec2::ONE),
        Anchor::CENTER,
    ));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-UIGraphical user interfaces, styles, layouts, and widgetsC-BugAn unexpected or incorrect behaviorP-RegressionFunctionality that used to work but no longer does. Add a test for this!

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions