bevyengine / bevyengine/bevy

Unified Bevy User Interface

Open
#22,345 6 comments 3 reactions 0 assignees View on GitHub
A-UI C-Feature S-Needs-Design-Doc
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

This issue is meant to be an overview of a broad effort to unify the various modes for user interaction in Bevy: the current `bevy_ui`, with it's CSS-like box model, as well as "diagetic" user interfaces drawn using a 2D or 3D camera.

In current Bevy, user interface elements (`Nodes`) live in their own hierarchy, separate from the 2D or 3D scene. This makes it easy to implement a "HUD" (Heads-Up Display) style of user interface, where the UI elements float above the 2D or 3D scene. However, many popular games don't easily fit within this visual structure, instead mixing different modalities within a single window.

## Examples

The inventory screen from _Borderlands: The Pre-Sequel_.

![Image](https://github.com/user-attachments/assets/c5f1e839-79f8-48de-b02b-8bc3e43894a4)

The skill tree screen from _Jedi: Fallen Order_:

Image

Another skill tree from _Path of Exile_:

![Image](https://github.com/user-attachments/assets/e518ac79-a8c5-4acb-a886-23563f2a4d08)

## Current Status

When we talk about integrating these different modes, we have to consider the various operations that are performed on these hierarchies. This includes picking, rendering, and navigation.

In terms of picking, we are actually in pretty good shape: bevy_picking supports multiple picking backends which can work seamlessly across ui nodes, 3d meshes, physics colliders, and other scene types.

For rendering, we have a number of challenges: first, the ui system uses a CSS-style box model and layout algorithm that is quite different from the way that 2d and 3d scenes are constructed. This model is very convenient for building adaptive and responsive UIs, but it's not always clear how to combine this model with 2d sprites or meshes.

The bevy_ui hierarchy also uses its own special global transform type, `UiGlobalTransform`. This was introduced in 2025 to simplify the computation of UI transforms (since UI didn't need the full power of GlobalTransform) but at the cost of further separating it from the 2D and 3D world.

UI also relies heavily on clipping algorithms for things like scrolling. We currently only support rectangular clipping regions (which are the easiest to implement and cheapest from a performance standpoint), but which are inadequate for the kinds of UIs we want to build. Unfortunately, there's no solution to the clipping problem which isn't expensive: path-based clip regions, off-screen render targets, or stencil buffers all have significant costs.

Finally, there is spatial navigation, which is kind of related to picking: this has only recently been introduced to Bevy, but the current proposal only works with UI hierarchies, not other kinds of scenes.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.