Как явно описать Z-порядок элементов пользовательского интерфейса с абсолютным позиционированием в bevy?

У меня такая ситуация:

  • Родитель Node, занимая все пространство экрана.
    • Ребенок для верхней планки.
    • Ребенок для игровой площадки.
    • Ребенок для нижней планки.
    • Абсолютно позиционированный дочерний элемент для наложения, который не должен быть привязан к трем указанным выше.

Я не могу заставить вышеуказанное работать, потому что я не могу найти способ определить z-порядок детей, по крайней мере, используя UiCameraComponents по умолчанию. Вот что я пробовал:

  • Добавление Translation компонент к абсолютно позиционированному дочернему элементу и переместите его вверх по оси Z.
  • Предоставление абсолютно позиционированному дочернему элементу преобразование выше по оси Z.
  • Создавайте узлы в разном порядке.

Кажется, что дочерний элемент наложения последовательно рендерится позади относительно расположенных братьев и сестер.

2 ответа

Порядок Z в пользовательском интерфейсе Bevy в настоящее время неявно определяется иерархией. Узлы "складываются" поверх своих родителей и над братьями и сестрами, которые идут перед ними в списке дочерних узлов их родителей.

Функционально z-порядок определяется с использованием значения z-трансляции Transform объекта. Для обычных спрайтов вы можете установить это напрямую. Для компонентов пользовательского интерфейса существует базовая система, которая устанавливает это за вас.

В конце концов, я хотел бы сделать возможным переопределение поведения Z-порядка Bevy UI. Это должно быть связано с добавлением нового поля для "отказа", а затем разрешением людям напрямую устанавливать z-преобразование.

В качестве обходного пути для текущего стабильного набора (0.7) я использую фиксированный z для узлов пользовательского интерфейса.

      #[derive(Debug, Component)]
pub(crate) struct UiFixedZ {
    pub z: f32,
}

pub(crate) fn ui_apply_fixed_z(
    mut node_query: Query<(&mut Transform, &mut GlobalTransform, &UiFixedZ), With<Node>>,
) {
    for (mut transform, mut global_transform, fixed) in node_query.iter_mut() {
        transform.translation.z = fixed.z;
        global_transform.translation.z = fixed.z;
    }
}

Я помещаю систему на последний этап сразу после системы z-порядка группы.

      ...
app.add_system_to_stage(CoreStage::Last, ui_apply_fixed_z)
...

при вставке компонентов UiFixedZ имейте в виду, что вам нужно позаботиться обо всех потомках вручную.

      ...
// inserting with manual z order
.insert(UiFixedZ { z: 101. })
...

   // inserting children with increased z order
   .insert(UiFixedZ { z: 102. })

надеюсь, обходной путь поможет кому-то. Я лично использую его для всплывающих подсказок. Скопировал свой комментарий с github :P


Беви молода, и в будущем ситуация может измениться.

Другие вопросы по тегам