Добавление различных вариантов макета из 2D-редактора

Я хотел бы сделать следующие виды для портретного и ландшафтного режима:

В портретной ориентации отображайте виды по вертикали как

A
B
C

(похоже, они находятся в VBox)

В альбомной ориентации виды отображаются как

A C
B

(выглядит как HBox (VBox (A, B), C))

Я могу сделать это с помощью настраиваемого контейнера, но это означает, что я сам измеряю размеры и требую, чтобы все 3 узла были непосредственными дочерними элементами моего контейнера.

Мне было интересно, есть ли другой подход, при котором мы можем определить два полностью отдельных макета в редакторе и связать определенные узлы с теми узлами, которые нам нужны; Это шаблон, с которым я более знаком по разработчикам Android, где мы можем создать два совершенно разных макета и связать определенные представления, имея один и тот же идентификатор.

В этом случае я мог бы создать макеты, о которых я упоминал выше, с существующими VBox и HBox, и указать корневой ноте разместить A, B, C там, где они должны быть. Дочерние элементы больше не должны быть непосредственными дочерними элементами корневого контейнера, и я могу добавлять другие узлы в один из макетов, а не в другой. Если пользователь переключается между этими двумя макетами, я ожидаю, что содержимое общих узлов (A, B, C) будет сохранено.

Есть ли способ сделать что-то подобное в Годо?


person Allan W    schedule 30.08.2020    source источник


Ответы (1)


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

extends Control
        
const LANDSCAPE_LAYOUT = preload("res://Landscape.tscn")
const PORTRAIT_LAYOUT = preload("res://Portrait.tscn")
var orientation = 0
onready var layout = $Layout // root node of UI you will replace

func _process(delta):
    if orientation != OS.screen_orientation:
        _change_layout()


func _change_layout():
    orientation = OS.screen_orientation
    var new_layout = null
    match orientation:
        0:
            new_layout = LANDSCAPE_LAYOUT.instance()
        1:
            new_layout = PORTRAIT_LAYOUT.instance()
        _:
            return  // feel free to include the other cases in ScreenOrientation enum.

    var layout_position = layout.get_position_in_parent()
    remove_child(layout)
    add_child(new_layout)
    move_child(new_layout, layout_position)
    layout = new_layout

Подобно жизненному циклу активности Android, вы уничтожаете и воссоздаете часть своего пользовательского интерфейса всякий раз, когда изменяется ориентация.

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

person JarWarren    schedule 31.08.2020
comment
Попробую это. Похоже, что move_child - это ключ - person Allan W; 31.08.2020