Search code examples
rusttransformbevy

How to center a entity in the window with Bevy?


I'm making a 2048 game in rust using bevy to learn about the game engine.

In this moment I'm making the scene with the main menu, but I'm having a problem to work with the Transform struct. Maybe is a problem with my understand of how Bevy works.

This is the function responsible of create the main menu.

pub fn main_menu(mut commands: Commands, asset_server: Res<AssetServer>) {
        commands
            .spawn(NodeBundle {
                style: Style {
                    size: Size {
                        width: Val::Percent(60.0),
                        height: Val::Percent(60.0),
                    },
                    ..default()
                },
   /* ------> */transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)), // <-------
                background_color: Color::rgba_u8(92, 64, 64, 35).into(),
                ..default()
            })
            .with_children(|parent| {
                // text
                parent.spawn(TextBundle {
                    text: Text {
                        sections: vec![TextSection {
                            value: "2048".to_string(),
                            style: TextStyle {
                                font: asset_server
                                    .load("font/Inconsolata-VariableFont_wdth,wght.ttf"),
                                font_size: 50.0,
                                color: Color::rgba_u8(168, 168, 168, 255).into(),
                            },
                        }],
                        ..Default::default()
                    },
                    ..Default::default()
                });
            });

        println!("Hello from main menu!!");
    }

I tried to use the Global Transform an the Transform structs but there is no difference.

I thought that could be a problem of using relative sizes by using percent, but I changed the size to using pixels instead and didn't work either.

The rectangle is rendered in the top left of the screen all the time.

Bevy window print

Do you know the rigth way to do this?


Solution

  • For some reason that I don't understand the transform is not working with elements that don't use a sprite, to solve the situation in this case I use the Style component for Nodes that follows a css approach, I think that is amaizing by the way.

    It works to create a simple ui, so I guess that is a victory for now.

    This is the result:

    pub fn main_menu(mut commands: Commands, asset_server: Res<AssetServer>) {
            // Main container for the main_menu interface
            commands
                .spawn(NodeBundle {
                    style: Style {
                        size: Size::width(Val::Percent(100.0)),
                        flex_direction: FlexDirection::Column,
                        justify_content: JustifyContent::Center,
                        align_items: AlignItems::Center,
                        ..default()
                    },
                    ..default()
                })
                .with_children(|parent| {
                    parent
                        .spawn(NodeBundle {
                            style: Style {
                                size: Size {
                                    width: Val::Percent(60.0),
                                    height: Val::Percent(75.0),
                                },
                                flex_direction: FlexDirection::Column,
                                justify_content: JustifyContent::Center,
                                align_items: AlignItems::Center,
                                ..default()
                            },
                            //background_color: Color::rgba_u8(92, 64, 64, 35).into(),
                            ..default()
                        })
                        // Game title
                        .with_children(|parent| {
                            parent.spawn(TextBundle {
                                text: Text {
                                    sections: vec![TextSection {
                                        value: "2048".to_string(),
                                        style: TextStyle {
                                            font: asset_server
                                                .load("font/Inconsolata-VariableFont_wdth,wght.ttf"),
                                            font_size: 75.0,
                                            color: Color::rgba_u8(168, 168, 168, 255).into(),
                                        },
                                    }],
                                    ..Default::default()
                                },
                                ..Default::default()
                            });
                        })
                        .with_children(|parent| {
                            parent
                                .spawn(ButtonBundle {
                                    style: Style {
                                        size: Size::new(Val::Percent(100.0), Val::Px(50.0)),
                                        // horizontally center child text
                                        justify_content: JustifyContent::Center,
                                        // vertically center child text
                                        align_items: AlignItems::Center,
                                        ..default()
                                    },
                                    ..default()
                                })
                                .with_children(|parent| {
                                    parent.spawn(TextBundle::from_section(
                                        "Play!",
                                        TextStyle {
                                            font: asset_server
                                                .load("font/Inconsolata-VariableFont_wdth,wght.ttf"),
                                            font_size: 30.0,
                                            color: Color::rgba_u8(168, 168, 168, 255).into(),
                                        },
                                    ));
                                });
                        })
                        .with_children(|parent| {
                            parent
                                .spawn(ButtonBundle {
                                    style: Style {
                                        size: Size::new(Val::Percent(100.0), Val::Px(50.0)),
                                        // horizontally center child text
                                        justify_content: JustifyContent::Center,
                                        // vertically center child text
                                        align_items: AlignItems::Center,
                                        ..default()
                                    },
                                    ..default()
                                })
                                .with_children(|parent| {
                                    parent.spawn(TextBundle::from_section(
                                        "Scores",
                                        TextStyle {
                                            font: asset_server
                                                .load("font/Inconsolata-VariableFont_wdth,wght.ttf"),
                                            font_size: 30.0,
                                            color: Color::rgba_u8(168, 168, 168, 255).into(),
                                        },
                                    ));
                                });
                        })
                        .with_children(|parent| {
                            parent
                                .spawn(ButtonBundle {
                                    style: Style {
                                        size: Size::new(Val::Percent(100.0), Val::Px(50.0)),
                                        // horizontally center child text
                                        justify_content: JustifyContent::Center,
                                        // vertically center child text
                                        align_items: AlignItems::Center,
                                        ..default()
                                    },
                                    ..default()
                                })
                                .with_children(|parent| {
                                    parent.spawn(TextBundle::from_section(
                                        "Exit",
                                        TextStyle {
                                            font: asset_server
                                                .load("font/Inconsolata-VariableFont_wdth,wght.ttf"),
                                            font_size: 30.0,
                                            color: Color::rgba_u8(168, 168, 168, 255).into(),
                                        },
                                    ));
                                });
                        });
                });
        }
    

    bevy ui print

    I actually followed a bevy example to solve this, here you can find it: bevy ui example