MCPcopy Index your code
hub / github.com/bytestring-net/bevy_lunex

github.com/bytestring-net/bevy_lunex @0.5.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release 0.5.0 ↗ · + Follow
230 symbols 326 edges 16 files 125 documented · 54% updated 4mo ago0.5.0 · 2025-10-20★ 9308 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

image

Blazingly fast retained layout engine for Bevy entities, built around vanilla Bevy ECS. It gives you the ability to make your own custom UI using regular ECS like every other part of your app.

  • Any aspect ratio: Lunex is designed to support ALL window sizes out of the box without deforming. The built in layout types react nicely and intuitively to aspect ratio changes.

  • Optimized: Unlike immediate mode GUI systems, Bevy_Lunex is a retained layout engine. This means the layout is calculated and stored, reducing the need for constant recalculations and offering potential performance benefits, especially for static or infrequently updated UIs.

  • ECS focused: Since it's built with ECS, you can extend or customize the behavior of your UI by simply adding or modifying components. The interactivity is done by regular systems and events.

  • Worldspace UI: One of the features of Bevy_Lunex is its support for both 2D and 3D UI elements, leveraging Bevy's Transform component. This opens up a wide range of possibilities for developers looking to integrate UI elements seamlessly into both flat and spatial environments. Diegetic UI is no problem.

image

Try out the live WASM demo on Itch.io (Limited performance & stutter due to running on a single thread). For best experience compile the project natively.

Syntax Example

This is an example of a clickable Button created from scratch using provided components. Thanks to ECS, the syntax is highly modular with strong emphasis on components-per-functionality. As you can see, it is no different from vanilla Bevy ECS.

```rust ignore // Create UI commands.spawn(( // Initialize the UI root for 2D UiLayoutRoot::new_2d(), // Make the UI synchronized with camera viewport size UiFetchFromCamera::<0>, )).with_children(|ui| {

// Spawn a button in the middle of the screen
ui.spawn((
    Name::new("My Button"),
    // Specify the position and size of the button
    UiLayout::window().pos(Rl((50.0, 50.0))).size((200.0, 50.0)).pack(),
    // When hovered, it will request the cursor icon to be changed
    OnHoverSetCursor::new(SystemCursorIcon::Pointer),
)).with_children(|ui| {

    // Spawn a child node but with a background
    ui.spawn((
        // You can define layouts for multiple states
        UiLayout::new(vec![
            // The default state, just fill the parent
            (UiBase::id(), UiLayout::window().full()),
            // The hover state, grow to 105% of the parent from center
            (UiHover::id(), UiLayout::window().anchor(Anchor::Center).size(Rl(105.0)))
        ]),
        // Enable the hover state and give it some properties
        UiHover::new().forward_speed(20.0).backward_speed(4.0),
        // You can specify colors for multiple states
        UiColor::new(vec![
            (UiBase::id(), Color::BEVYPUNK_RED.with_alpha(0.15)),
            (UiHover::id(), Color::BEVYPUNK_YELLOW.with_alpha(1.2))
        ]),
        // You can attach any form of rendering to the node, be it sprite, mesh or something custom
        Sprite {
            image: asset_server.load("images/button.png"),
            // Here we enable sprite slicing
            image_mode: SpriteImageMode::Sliced(TextureSlicer { border: BorderRect::all(32.0), ..Default::default() }),
            ..Default::default()
        },
        // Make sure it does not cover the bounding zone of parent
        Pickable::IGNORE,
    )).with_children(|ui| {

        // Spawn a text child node
        ui.spawn((
            // For text we always use window layout to position it. The size is computed at runtime from text bounds
            UiLayout::window().pos((Rh(40.0), Rl(50.0))).anchor(Anchor::CenterLeft).pack(),
            UiColor::new(vec![
                (UiBase::id(), Color::BEVYPUNK_RED),
                (UiHover::id(), Color::BEVYPUNK_YELLOW.with_alpha(1.2))
            ]),
            UiHover::new().forward_speed(20.0).backward_speed(4.0),
            // Here we specify the text height proportional to the parent node
            UiTextSize::from(Rh(60.0)),
            // You can attach text like this
            Text2d::new("Click me!"),
            TextFont {
                font: asset_server.load("fonts/semibold.ttf"),
                font_size: 64.0,
                ..Default::default()
            },
            // Make sure it does not cover the bounding zone of parent
            Pickable::IGNORE,
        ));
    });
})
// Utility observers that enable the hover state on trigger
.observe(hover_set::<Pointer<Over>, true>)
.observe(hover_set::<Pointer<Out>, false>)
// Interactivity is done through observers, you can query anything here
.observe(|_: Trigger<Pointer<Click>>| {
    println!("I was clicked!");
});

}); ```

Documentation

Contributing

Any contribution submitted by you will be dual licensed as mentioned below, without any additional terms or conditions. If you have the need to discuss this, please contact me.

Licensing

Released under both APACHE and MIT licenses. Pick one that suits you the most!

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Method 99
Function 65
Class 55
Enum 6
Interface 5

Languages

Rust100%

Modules by API surface

crate/src/lib.rs68 symbols
crate/src/layouts.rs52 symbols
crate/src/cursor.rs28 symbols
crate/src/states.rs20 symbols
crate/src/textanim.rs18 symbols
crate/src/units.rs13 symbols
examples/text3d/src/boilerplate.rs4 symbols
examples/sprite3d/src/boilerplate.rs4 symbols
examples/pixelated_dualcamera/src/main.rs4 symbols
examples/mesh2d/src/main.rs4 symbols
crate/src/picking.rs4 symbols
examples/dualcamera/src/main.rs3 symbols

For agents

$ claude mcp add bevy_lunex \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page