bevy icon indicating copy to clipboard operation
bevy copied to clipboard

UI only visible for one frame when used with animated sprites

Open tsukinoko-kun opened this issue 1 year ago • 1 comments

Bevy version

0.14.0

[Optional] Relevant system information

System independent.

(Tested on macOS 14.5 M2 and WASM)

What you did

Added UI overlay to gameplay.

What went wrong

UI not visible in gameplay (when 2D sprites are animated).
UI appears for one frame if I resize the window.

The same kind of UI used for the main-menu and pause-menu is working as expected.

Additional information

video recording

https://youtu.be/fPNzRPJ694c

Code: https://github.com/bloodmagesoftware/mageanoid/tree/12ec2d4637218cca65c511161e56116a254b1521

repo: https://github.com/bloodmagesoftware/mageanoid.git
commit: 12ec2d4637218cca65c511161e56116a254b1521

UI is in src/gameplay/hud.rs. Camera is in src/cam.rs.

tsukinoko-kun avatar Jul 09 '24 12:07 tsukinoko-kun

Update

I added a background and now the UI is rendered as expected.

use bevy::prelude::*;

use crate::gameplay::overlap::StaticObject;

const Z_INDEX: f32 = -100.0;

fn spawn_level(mut commands: Commands, asset_server: Res<AssetServer>) {
    let ground = SpriteBundle {
        texture: asset_server.load("levels/Untitled/png/Level_0__Ground.png"),
        transform: Transform::from_translation(Vec3::new(0.0, 0.0, Z_INDEX)),
        ..default()
    };

    let rock = SpriteBundle {
        texture: asset_server.load("levels/Untitled/png/Level_0__Rock.png"),
        transform: Transform::from_translation(Vec3::new(0.0, 0.0, Z_INDEX + 1.0)),
        ..default()
    };

    commands
        .spawn((StaticObject, ground))
        .with_children(|parent| {
            parent.spawn((StaticObject, rock));
        });
}

pub struct LdtkPlugin;

impl Plugin for LdtkPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Startup, spawn_level);
    }
}
Screenshot 2024-07-09 at 16 01 03

tsukinoko-kun avatar Jul 09 '24 14:07 tsukinoko-kun

Reproduced half of it:

use bevy::prelude::*;

#[derive(Component)]
struct Behind;

fn setup(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());
    let health_bar_inner = NodeBundle {
        style: Style {
            width: Val::Percent(20.0),
            height: Val::Percent(20.0),
            ..default()
        },
        background_color: Color::srgb(0.8, 0.1, 0.1).into(),
        ..default()
    };

    commands.spawn((health_bar_inner, Behind));
}

fn overlap(mut transform_q: Query<&mut Transform, With<Behind>>) {
    for mut transform in transform_q.iter_mut() {
        transform.translation.z = -transform.translation.y;
    }
}

fn main() {
    let mut app = App::new();

    app.add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, overlap);

    app.run();
}

The UI disappearing is caused by playing with the UI's z-index. I have no idea why adding a background fixed it, though. Could not reproduce that. I tried putting a sprite behind it, didn't work.

SmakoszJan avatar Aug 29 '24 10:08 SmakoszJan

Correction: here's something more minimal:

use bevy::prelude::*;

#[derive(Component)]
struct Behind;

fn setup(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());
    let health_bar_inner = NodeBundle {
        style: Style {
            width: Val::Percent(20.0),
            height: Val::Percent(20.0),
            ..default()
        },
        background_color: Color::srgb(0.8, 0.1, 0.1).into(),
        ..default()
    };

    commands.spawn((health_bar_inner, Behind));
}

fn overlap(mut transform_q: Query<&mut Transform, With<Behind>>) {
    transform_q.single_mut().translation.z = -1.0;
}

fn main() {
    let mut app = App::new();

    app.add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, overlap);

    app.run();
}

SmakoszJan avatar Aug 29 '24 11:08 SmakoszJan

To be clear: with background I meant Sprites. In my case, I had one Sprite covering the whole scene. I didn't investigate further because my problem was kind of solved.

tsukinoko-kun avatar Sep 06 '24 20:09 tsukinoko-kun

It's expected that UI nodes with negative z transforms are not drawn.

Note that the z value of the transform is not the "z index." To control the order your UI nodes drawn in, you want to use ZIndex and/or GlobalZIndex.

Bevy's UI layout system manages the transforms of UI nodes.

rparrett avatar Feb 09 '25 15:02 rparrett