Как явно описать 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
Беви молода, и в будущем ситуация может измениться.