reckfellENGINE

Размеры Control: привязки, отступы и ограничения

Рабочий HUD у правого и нижнего края, формула привязки, minimum/maximum и причина сброса размера.

На этой странице

Четыре края вместо одной позиции

Каждый край Control вычисляется относительно области привязки родителя: край = anchor × размер_родителя + offset. Для левого/правого края используется ширина, для верхнего/нижнего — высота. Anchor 0 соответствует началу оси, 1 — концу. Offset задаётся в логических пикселях интерфейса. После расчёта действуют ограничения размеров и направление роста.

РазмещениеAnchorsOffsets
Правый верхний HUD шириной 160Left = Right = 1, Top = Bottom = 0Left -176, Right -16, Top 16, Bottom 80
Нижняя растянутая панельLeft 0, Right 1, Top = Bottom = 1Left 16, Right -16, Top -80, Bottom -16
Заполнить родителяFullRectНулевые отступы

В первом случае при ширине родителя 960 левый край равен 784, правый 944: до края остаётся 16. При ширине 390 левый край становится 214, а ширина остаётся 160. Это не масштабирование содержимого.

Запустить пример

Добавьте UiSampleStyle.cs. Прикрепите AnchorsDemo.cs ниже к корню Control отдельного уровня, соберите и запустите F6. Меняйте размер окна: HP остаётся сверху справа, нижняя панель растягивается, синий прямоугольник сохраняет заданные пределы размера.

AnchorsDemo.cs
C#
using Reckfell;

public partial class AnchorsDemo : Control
{
    public PanelContainer Hud { get; private set; } = null!;
    public PanelContainer Bottom { get; private set; } = null!;
    public Control Bounded { get; private set; } = null!;

    public override void _Ready()
    {
        UiSampleStyle.Prepare(this);
        Hud = new PanelContainer { Name = "Hud" }; AddChild(Hud);
        Hud.AddChild(new Label { Text = "HP 100", HorizontalAlignment = HorizontalAlignment.Center });
        Hud.SetAnchorsPreset(LayoutPreset.TopRight);
        Hud.SetOffset(Side.Left, -176); Hud.SetOffset(Side.Right, -16);
        Hud.SetOffset(Side.Top, 16); Hud.SetOffset(Side.Bottom, 80);
        Bottom = new PanelContainer { Name = "Bottom" }; AddChild(Bottom);
        Bottom.AddChild(new Label { Text = UiSampleStyle.Text("Панель у нижнего края", "Bottom-edge panel") });
        Bottom.SetAnchorsPreset(LayoutPreset.BottomWide);
        Bottom.SetOffset(Side.Left, 16); Bottom.SetOffset(Side.Right, -16);
        Bottom.SetOffset(Side.Top, -80); Bottom.SetOffset(Side.Bottom, -16);
        Bounded = new ColorRect
        {
            Name = "Bounded", Color = new Color(.15f, .35f, 1), Position = new Vector2(16, 110),
            CustomMinimumSize = new Vector2(64, 32), CustomMaximumSize = new Vector2(160, 90),
            MouseFilter = MouseFilterEnum.Ignore
        };
        AddChild(Bounded); Bounded.Size = new Vector2(999, 999);
    }
}

Сначала назначается готовый набор anchors, затем offsets. Это избавляет от промежуточного конфликта противоположных привязок. У SetAnchor/SetAnchorAndOffset есть параметры сохранения offsets и сдвига противоположной привязки; порядок отдельных присваиваний может влиять на результат. Не заменяйте ими preset, если нужен стандартный вариант.

SetAnchorsPreset(FullRect) не означает нулевые offsets: с keepOffsets = false привязки меняются с пересчётом offsets для сохранения текущего прямоугольника; true сохраняет численные offsets. Для заполнения родителя с согласованными offsets используйте SetAnchorsAndOffsetsPreset(FullRect) и нужный margin, как у корня примера. Проверьте итоговый Size после применения minimum/maximum.

Minimum и Maximum

Встроенный минимум зависит от текста, шрифта, темы и содержимого контейнера. CustomMinimumSize задаёт дополнительный минимум, а не окончательный размер. Смотрите GetCombinedMinimumSize() для результирующего требования.

CustomMaximumSize ограничивает размер по осям. В примере попытка задать 999 × 999 даёт 160 × 90; попытка задать ноль даёт 64 × 32. Отрицательная компонента maximum означает отсутствие ограничения на этой оси; ноль не означает «без ограничения». Не задавайте minimum больше maximum. Вложенные элементы и контейнеры также могут влиять на ограничения; проверяйте итоговую раскладку, а не только введённое поле.

GrowHorizontal и GrowVertical определяют, в какую сторону меняется прямоугольник при ограничениях: Begin, End или Both. Это не коэффициент увеличения рисунка. Scale тоже не заменяет корректный размер и может мешать ожиданиям от контейнера.

Где привязки не решают задачу

Прямым дочерним Control контейнера управляет контейнер. Настраивайте minimum/maximum и SizeFlags, а не Position каждый кадр. FullRect на родителе не заполняет автоматически всю остальную иерархию. Если интерфейс ниже viewport, ему нужен прокручиваемый контейнер или другая компоновка, а не отрицательный размер.

То же меню после изменения области на 390 на 844

Этот снимок относится к ResponsiveMenu: карточка стала уже, надпись перенеслась, размер шрифта сохранился. Изменение логической области UI, растяжение рендера и системный DPI — разные настройки.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.