#ui #bevy #gamedev #ui-elements

bevy_state_ui

A simple UI library for rendering a UI from a given state

5 releases (3 breaking)

0.4.0 Dec 3, 2024
0.3.0 Nov 17, 2024
0.2.0 Nov 17, 2024
0.1.1 Oct 25, 2024
0.1.0 Oct 25, 2024

#835 in Game dev

Download history 175/week @ 2024-10-21 29/week @ 2024-10-28 28/week @ 2024-11-04 51/week @ 2024-11-11 181/week @ 2024-11-18 35/week @ 2024-11-25 254/week @ 2024-12-02 58/week @ 2024-12-09

579 downloads per month

MIT license

30KB
55 lines

Bevy State UI

This library provides a simple and flexible way to render UI elements in Bevy based on a given application state. Using bevy_state_ui, you can bind UI elements to state properties and update them in real-time as the state changes.

Features

  • State-Driven UI Rendering: Renders a UI based directly on state values, allowing for a clean separation between logic and presentation. This simplifies complex UI management by reducing the need for manual component manipulation.
  • Automatic UI Element Registration: By implementing the Render trait on a custom state, UI elements are automatically registered and rendered based on the state.
  • Interaction-Based State Updates: Provides easy handling of standard UI interactions (e.g., hover, press) by defining state updates within Bevy systems, making the UI more reactive to user input.

Installation

Add bevy_state_ui to your Cargo.toml dependencies:

[dependencies]
bevy = "0.14.2"
bevy_state_ui = "0.3.0"

Example Usage

Here's how you can set up a simple UI with a button that changes color when hovered.

Example:

use bevy::prelude::*;
use bevy_state_ui::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, update_button_interactions)
        .register_ui_state::<State>()
        .add_systems(
            Update,
            render
                .run_if(ui_state_changed::<State>),
        )
        .run();
}

#[derive(Resource, Hash)]
pub struct State {
    pub hovered: bool,
}

fn render(mut commands: Commands, state: Res<State>) {
    commands.with_children(|parent| {
        parent.spawn(ButtonBundle {
            style: Style { width: Val::Percent(40.0), height: Val::Percent(15.0), ..default() },
            background_color: if state.hovered { Color::WHITE.into() } else { Color::BLACK.into() },
            ..default()
        }).with_children(|parent| {
            parent.spawn(TextBundle::from_section("I am a button", TextStyle { font_size: 40.0, ..default() }));
        });
    });
}


fn update_button_interactions(mut state: ResMut<State>, q: Query<&Interaction, (Changed<Interaction>, With<Button>)>) {
    if let Some(&interaction) = q.iter().next() {
        state.hovered = matches!(interaction, Interaction::Hovered);
    }
}

Dependencies

~53–85MB
~1.5M SLoC