https://github.com/bytestring-net/bevy_lunex
Blazingly fast retained layout engine for Bevy ECS.
https://github.com/bytestring-net/bevy_lunex
bevy bevy-lunex framework layout lunex rust ui
Last synced: 6 days ago
JSON representation
Blazingly fast retained layout engine for Bevy ECS.
- Host: GitHub
- URL: https://github.com/bytestring-net/bevy_lunex
- Owner: bytestring-net
- License: apache-2.0
- Created: 2023-06-26T20:44:39.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-03-25T07:54:25.000Z (26 days ago)
- Last Synced: 2025-04-07T09:07:13.632Z (13 days ago)
- Topics: bevy, bevy-lunex, framework, layout, lunex, rust, ui
- Language: Rust
- Homepage: https://bytestring-net.github.io/bevy_lunex/
- Size: 82.7 MB
- Stars: 700
- Watchers: 6
- Forks: 30
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
- awesome-bevy - Lunex
- awesome-bevy - `bevy_lunex`
- awesome-bevy - `bevy_lunex`
README

#
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.
##

> *Try out the live WASM demo on [`Itch.io`](https://idedary.itch.io/bevypunk) (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
// 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::square(32.0), ..default() }),
..default()
},
// Make sure it does not cover the bounding zone of parent
PickingBehavior::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()
},
// Make sure it does not cover the bounding zone of parent
PickingBehavior::IGNORE,
));
});
})
// Utility observers that enable the hover state on trigger
.observe(hover_set::, true>)
.observe(hover_set::, false>)
// Interactivity is done through observers, you can query anything here
.observe(|_: Trigger>| {
// ... Do something on click
});
});
```## Documentation
- The Lunex Book: [`Bevy Lunex book`](https://bytestring-net.github.io/bevy_lunex/).
- Highly documented source code on Docs.rs: [`Docs.rs`](https://docs.rs/bevy_lunex/latest/bevy_lunex/).
- Highly documented production-ready example: [`Bevypunk example`](https://github.com/IDEDARY/Bevypunk).
## 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](./LICENSE-APACHE) and [MIT](./LICENSE-MIT) licenses. Pick one that suits you the most!