Экспортированные свойства C#
В Godot члены класса могут быть экспортированы. Это означает, что их значение сохраняется вместе с ресурсом (например, scene), к которому они прикреплены. Они также будут доступны для редактирования в редакторе свойств. Экспорт выполняется с помощью атрибута [Export].
using Godot;
public partial class ExportExample : Node3D
{
[Export]
public int Number { get; set; } = 5;
}
В этом примере значение 5 будет сохранено, и после построения текущего проекта оно будет видно в редакторе свойств.
Одним из фундаментальных преимуществ экспорта переменных (членов класса) является то, что они видны и редактируются в редакторе. Таким образом, художники и гейм-дизайнеры могут изменять значения, которые впоследствии будут влиять на работу программы. Для этого предусмотрен специальный синтаксис экспорта.
Экспорт возможен только с помощью Variant-compatible типы.
Примечание
Экспорт свойств также можно выполнить в GDScript, информацию об этом см. в Экспортируемые свойства GDScript.
Основное применение
Экспорт работает с полями и свойствами. Они могут иметь любой модификатор доступа.
[Export]
private int _number;
[Export]
public int Number { get; set; }
Экспортированные элементы могут указывать значение по умолчанию; в противном случае вместо него используется значение по умолчанию типа.
int, например Number, по умолчанию равен 0. Text по умолчанию равен null, поскольку string является ссылочным типом.
[Export]
public int Number { get; set; }
[Export]
public string Text { get; set; }
Для полей и свойств можно указать значения по умолчанию.
[Export]
private string _greeting = "Hello World";
[Export]
public string Greeting { get; set; } = "Hello World";
Свойства с резервным полем используют значение резервного поля по умолчанию.
private int _number = 2;
[Export]
public int NumberWithBackingField
{
get => _number;
set => _number = value;
}
Примечание
Метод get свойства фактически не выполняется для определения значения по умолчанию. Вместо этого Godot анализирует исходный код C#. Это работает нормально в большинстве случаев, например, в примерах на этой странице. Однако некоторые свойства слишком сложны для понимания анализатором.
Например, следующее свойство пытается использовать математику для отображения значения по умолчанию как 5 в редакторе свойств, но это не работает:
[Export]
public int NumberWithBackingField
{
get => _number + 3;
set => _number = value - 3;
}
private int _number = 2;
Анализатор не распознает этот код и возвращается к значению по умолчанию для int, 0. Однако при запуске сцены или проверке узла с прикреплённым скриптом инструмента _number будет равно 2, а NumberWithBackingField вернёт 5. Это различие может привести к запутанному поведению. Чтобы избежать этого, не используйте сложные свойства. В качестве альтернативы, если значение по умолчанию можно указать явно, его можно переопределить с помощью методов _PropertyCanRevert() и _PropertyGetRevert().
Можно экспортировать любой тип Resource или Node. Редактор свойств отображает удобный диалог назначения для этих типов. Его можно использовать вместо GD.Load и GetNode. См. Nodes and Resources.
[Export]
public PackedScene PackedScene { get; set; }
[Export]
public RigidBody2D RigidBody2D { get; set; }
Группировка экспорта
Экспортированные свойства можно сгруппировать в Инспекторе с помощью атрибута [ExportGroup]. Каждое экспортированное свойство после этого атрибута будет добавлено в группу. Создайте новую группу или используйте [ExportGroup("")] для разбиения.
[ExportGroup("My Properties")]
[Export]
public int Number { get; set; } = 3;
Второй аргумент атрибута можно использовать только для группировки свойств с указанным префиксом.
Группы не могут быть вложенными, используйте [ExportSubgroup] для создания подгрупп внутри группы.
[ExportSubgroup("Extra Properties")]
[Export]
public string Text { get; set; } = "";
[Export]
public bool Flag { get; set; } = false;
Вы также можете изменить название основной категории или создать дополнительные категории в списке свойств с помощью атрибута [ExportCategory].
[ExportCategory("Main Category")]
[Export]
public int Number { get; set; } = 3;
[Export]
public string Text { get; set; } = "";
[ExportCategory("Extra Category")]
[Export]
public bool Flag { get; set; } = false;
Примечание
Список свойств организован на основе наследования классов, и новые категории нарушают это ожидание. Используйте их с осторожностью, особенно при создании проектов для публичного использования.
Строки как пути
Подсказки свойств можно использовать для экспорта строк в виде путей
Строка как путь к файлу.
[Export(PropertyHint.File)]
public string GameFile { get; set; }
Строка как путь к каталогу.
[Export(PropertyHint.Dir)]
public string GameDirectory { get; set; }
Строка как путь к файлу, пользовательский фильтр предоставлен в качестве подсказки.
[Export(PropertyHint.File, "*.txt,")]
public string GameFile { get; set; }
Использование путей в глобальной файловой системе также возможно, но только в скриптах в режиме инструмента.
Строка как путь к PNG-файлу в глобальной файловой системе.
[Export(PropertyHint.GlobalFile, "*.png")]
public string ToolImage { get; set; }
Строка как путь к каталогу в глобальной файловой системе.
[Export(PropertyHint.GlobalDir)]
public string ToolDir { get; set; }
Многострочная аннотация сообщает редактору о необходимости отобразить большое поле ввода для редактирования нескольких строк.
[Export(PropertyHint.MultilineText)]
public string Text { get; set; }
Ограничение диапазонов ввода редактора
Использование подсказки свойства диапазона позволяет ограничить то, что можно ввести в качестве значения с помощью редактора.
Допустимы целые значения от 0 до 20.
[Export(PropertyHint.Range, "0,20,")]
public int Number { get; set; }
Допустимы целые значения от -10 до 20.
[Export(PropertyHint.Range, "-10,20,")]
public int Number { get; set; }
Разрешить значения с плавающей точкой от -10 до 20 и привязать их к значениям, кратным 0,2.
[Export(PropertyHint.Range, "-10,20,0.2")]
public float Number { get; set; }
Если добавить подсказки "or_greater" и/или "or_less", то при настройке значения можно будет выйти за пределы, введя его вручную, а не используя ползунок.
[Export(PropertyHint.Range, "0,100,1,or_greater,or_less")]
public int Number { get; set; }
Поплавки с подсказкой о смягчении
Отобразить визуальное представление функции ease при редактировании.
[Export(PropertyHint.ExpEasing)]
public float TransitionSpeed { get; set; }
Экспорт с подсказкой суффикса
Отображает суффикс единицы измерения для экспортируемых переменных. Работает с числовыми типами, такими как числа с плавающей точкой или векторы:
[Export(PropertyHint.None, "suffix:m/s\u00b2")]
public float Gravity { get; set; } = 9.8f;
[Export(PropertyHint.None, "suffix:m/s")]
public Vector3 Velocity { get; set; }
В приведенном выше примере \u00b2 используется для записи символа "в кубе" (²).
Цвета
Обычный цвет задается как значение красный-зеленый-синий-альфа.
[Export]
public Color Color { get; set; }
Цвет задается как значение красного-зеленого-синего (альфа всегда будет равна 1).
[Export(PropertyHint.ColorNoAlpha)]
public Color Color { get; set; }
Узлы
Nodes can also be directly exported without having to use NodePaths.
[Export]
public Node Node { get; set; }
Также можно напрямую экспортировать определённый тип узла. Список узлов, отображаемый после нажатия кнопки "Assign" в инспекторе, фильтруется по указанному типу, и назначить можно только нужный узел.
[Export]
public Sprite2D Sprite2D { get; set; }
Пользовательские классы узлов также можно экспортировать напрямую. Поведение фильтрации зависит от того, является ли пользовательский класс global class.
Экспорт NodePaths, как в Godot 3.x, по-прежнему возможен, если он вам нужен:
[Export]
public NodePath NodePath { get; set; }
public override void _Ready()
{
var node = GetNode(NodePath);
}
Ресурсы
[Export]
public Resource Resource { get; set; }
Затем в Инспекторе можно перетащить файл ресурса из дока FileSystem в слот переменной.
Однако при открытии раскрывающегося списка инспектора может появиться очень длинный список возможных классов для создания. Поэтому, если указать тип, производный от Resource, например:
[Export]
public AnimationNode AnimationNode { get; set; }
В раскрывающемся меню будут доступны только AnimationNode и все его производные классы. Также можно использовать пользовательские классы ресурсов, см. Глобальные классы C#.
Следует отметить, что даже если во время работы в редакторе скрипт не выполняется, экспортируемые свойства все равно можно редактировать. Это можно использовать в сочетании с режимом "инструмента":.
Экспорт битовых флагов
Элементы типа enum с атрибутом [Flags] можно экспортировать, и их значения ограничены элементами типа enum. Редактор создаст виджет в Инспекторе, позволяющий выбрать один или несколько элементов enum, а также ни одного. Значение будет сохранено как целое число.
Перечисление флагов использует степени числа 2 для значений элементов перечисления. Также возможны элементы, объединяющие несколько флагов с помощью логического ИЛИ (|).
[Flags]
public enum SpellElements
{
Fire = 1 << 1,
Water = 1 << 2,
Earth = 1 << 3,
Wind = 1 << 4,
FireAndWater = Fire | Water,
}
[Export]
public SpellElements MySpellElements { get; set; }
Целые числа, используемые в качестве битовых флагов, могут хранить несколько значений true/false (логических) в одном свойстве. Используя подсказку свойства Flags, любой из указанных флагов может быть установлен из редактора.
[Export(PropertyHint.Flags, "Fire,Water,Earth,Wind")]
public int SpellElements { get; set; } = 0;
Необходимо предоставить строковое описание для каждого флага. В этом примере Fire имеет значение 1, Water — значение 2, Earth — значение 4, а Wind соответствует значению 8. Обычно константы определяются соответствующим образом (например, private const int ElementWind = 8 и т. д.).
Вы можете добавить явные значения, используя двоеточие:
[Export(PropertyHint.Flags, "Self:4,Allies:8,Foes:16")]
public int SpellTargets { get; set; } = 0;
В качестве битовых флагов допустимы только значения, являющиеся степенью двойки. Минимальное допустимое значение — 1, поскольку 0 означает, что ничего не выбрано. Вы также можете добавлять параметры, представляющие собой комбинацию других флагов:
[Export(PropertyHint.Flags, "Self:4,Allies:8,Self and Allies:12,Foes:16")]
public int SpellTargets { get; set; } = 0;
Экспортные аннотации также предоставляются для слоев физики и рендеринга, определенных в настройках проекта.
[Export(PropertyHint.Layers2DPhysics)]
public uint Layers2DPhysics { get; set; }
[Export(PropertyHint.Layers2DRender)]
public uint Layers2DRender { get; set; }
[Export(PropertyHint.Layers3DPhysics)]
public uint Layers3DPhysics { get; set; }
[Export(PropertyHint.Layers3DRender)]
public uint Layers3DRender { get; set; }
Использование бинарных флагов требует некоторого понимания побитовых операций. Если вы сомневаетесь, вместо этого следует экспортировать логические переменные.
Exporting enums (Экспорт перечислений)
Члены, тип которых является перечисление (enum), могут экспортироваться и их значения ограничиваются членами типа enum. Редактор создаст виджет в Inspector, перечисляя следующее как "Thing 1", "Thing 2", "Another Thing". Значение будет храниться как целое число.
public enum MyEnum
{
Thing1,
Thing2,
AnotherThing = -1,
}
[Export]
public MyEnum MyEnumCurrent { get; set; }
Интегерные и струнные члены также могут быть ограничены конкретным списком значений, используя аннотацию [Export] с PropertyHint.Enum подсказка. Редактор создаст виджет в Инспекторе, перечисляя следующее: Warrior, Magician, Thief. Значение будет храниться как целое число, соответствующее индексу выбранного варианта (т.е. 0, 1 или 2).
[Export(PropertyHint.Enum, "Warrior,Magician,Thief")]
public int CharacterClass { get; set; }
Вы можете добавить явные значения, используя двоеточие:
[Export(PropertyHint.Enum, "Slow:30,Average:60,Very Fast:200")]
public int CharacterSpeed { get; set; }
Если тип - string, значение будет сохранено как строка.
[Export(PropertyHint.Enum, "Rebecca,Mary,Leah")]
public string CharacterName { get; set; }
Если вы хотите задать начальное значение, его необходимо указать явно:
[Export(PropertyHint.Enum, "Rebecca,Mary,Leah")]
public string CharacterName { get; set; } = "Rebecca";
Экспорт коллекций
Как поясняется в документации C# Variant, только некоторые массивы C# и типы коллекций, определенные в namespace (пространстве имен) Godot.Collections являются совместимыми с Variant, поэтому только эти типы могут быть экспортированы.
Экспорт массивов Godot
[Export]
public Godot.Collections.Array Array { get; set; }
Использование универсального класса Godot.Collections. Array<T> позволяет указывать тип элементов массива, который будет использоваться в качестве подсказки для редактора. Инспектор ограничит эти элементы указанным типом.
[Export]
public Godot.Collections.Array<string> Array { get; set; }
По умолчанию значение массивов Godot является нулевым. Можно указать другое значение по умолчанию:
[Export]
public Godot.Collections.Array<string> CharacterNames { get; set; } =
[
"Rebecca",
"Mary",
"Leah",
];
Массивы с указанными типами, наследующими от ресурса, можно задать путем перетаскивания нескольких файлов из дока Файловой Системы.
[Export]
public Godot.Collections.Array<Texture> Textures { get; set; }
[Export]
public Godot.Collections.Array<PackedScene> Scenes { get; set; }
Экспорт словарей Godot
[Export]
public Godot.Collections.Dictionary Dictionary { get; set; }
Использование универсального Godot.Collections. Dictionary<TKey, TValue> позволяет указывать типы ключей и элементов значений словаря.
[Export]
public Godot.Collections.Dictionary<string, int> Dictionary { get; set; }
По умолчанию значение словарей Godot является нулевым. Можно указать другое значение по умолчанию:
[Export]
public Godot.Collections.Dictionary<string, int> CharacterLives { get; set; } = new Godot.Collections.Dictionary<string, int>
{
["Rebecca"] = 10,
["Mary"] = 42,
["Leah"] = 0,
};
Экспорт массивов C#
C# массивы могут экспортироваться до тех пор, пока тип элемента является Variant-compatible type.
[Export]
public Vector3[] Vectors { get; set; }
[Export]
public NodePath[] NodePaths { get; set; }
По умолчанию значение C# массивов является нулевым. Можно указать другое значение по умолчанию:
[Export]
public Vector3[] Vectors { get; set; } =
[
new Vector3(1, 2, 3),
new Vector3(3, 2, 1),
];
Установка экспортированных переменных из скрипта инструмента
При изменении значения экспортированной переменной из скрипта в Режим Инструмента значение в инспекторе не будет обновлено автоматически. Чтобы обновить его, вызовите NotifyPropertyListChanged() после установки значения экспортированной переменной.
Расширенный экспорт
Не каждый тип экспорта может быть предоставлен на уровне самого языка, чтобы избежать ненужной сложности проектирования. Далее описаны некоторые более или менее распространенные функции экспорта, которые могут быть реализованы с помощью низкоуровневого API.
Прежде чем читать дальше, вам следует ознакомиться со способом обработки свойств и тем, как их можно настраивать с помощью методов _Set(), _Get() и _GetPropertyList(), как описано в Доступ к данным или логике из объекта.
См. также
Свойства привязки, использующие описанные выше методы в C++, см. в разделе Связывание свойств через _set/_get/_get_property_list.
Предупреждение
Скрипт должен работать в режиме tool, чтобы вышеперечисленные методы могли работать из редактора.