Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Експортовані властивості C#

У Godot члени класу можна експортувати. Це означає, що їх значення буде збережено разом з ресурсом (наприклад, scene), до якого вони приєднані. Вони також будуть доступні для редагування у редакторі властивостей. Експорт здійснюється за допомогою атрибута [Export].

using Godot;

public partial class ExportExample : Node3D
{
    [Export]
    public int Number { get; set; } = 5;
}

У цьому прикладі значення 5 буде збережено, і після створення поточного проекту воно буде видимим у редакторі властивостей.

Однією з основних переваг експорту змінних є те, що їх можна побачити та редагувати у редакторі. Таким чином, художники та розробники ігор можуть змінювати значення, які згодом впливають на роботу програми. Для цього передбачений спеціальний синтаксис експорту.

Експорт можна виконати лише за допомогою Типи, сумісні з варіантами.

Примітка

Експорт властивостей також можна виконати в GDScript, інформацію про це див. Експортовані властивості GDScript.

Основне використання

Експорт працює з полями та властивостями. Вони можуть мати будь-який модифікатор доступу.

[Export]
private int _number;

[Export]
public int Number { get; set; }

Експортовані члени можуть вказати значення за замовчуванням; інакше замість нього використовується значення за замовчуванням типу.

int як Number за замовчуванням 0. Текст за умовчанням має значення null, оскільки рядок є типом посилання.

[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 властивості фактично не виконується для визначення значення за умовчанням. Натомість Годо аналізує вихідний код 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().

Можна експортувати будь-який тип Ресурс або Вузол. Редактор властивостей показує зручне діалогове вікно призначення для цих типів. Це можна використовувати замість GD.Load і GetNode. Перегляньте Вузли та ресурси.

[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; }

Плаває з натяком на полегшення

Display a visual representation of the ease function when editing.

[Export(PropertyHint.ExpEasing)]
public float TransitionSpeed { get; set; }

Export with suffix hint

Display a unit hint suffix for exported variables. Works with numeric types, such as floats or vectors:

[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; }

In the above example, \u00b2 is used to write the "squared" character (²).

Кольори

Звичайний колір у вигляді червоно-зелено-синього альфа-значення.

[Export]
public Color Color { get; set; }

Колір, поданий як значення червоно-зелено-синього (альфа завжди буде 1).

[Export(PropertyHint.ColorNoAlpha)]
public Color Color { get; set; }

Вузли

Починаючи з Godot 4.0, вузли можна експортувати безпосередньо без використання NodePaths.

[Export]
public Node Node { get; set; }

Певний тип вузла також можна безпосередньо експортувати. Список вузлів, який відображається після натискання «Призначити» в інспекторі, фільтрується за вказаним типом, і можна призначити лише правильний вузол.

[Export]
public Sprite2D Sprite2D { get; set; }

Спеціальні класи вузлів також можна експортувати безпосередньо. Поведінка фільтрації залежить від того, чи є власний клас глобальним класом.

Експорт 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 у слот для змінних.

Однак відкриття спадного меню інспектора може призвести до надзвичайно довгого списку можливих класів для створення. Таким чином, якщо ви вкажете тип, похідний від ресурсу, наприклад:

[Export]
public AnimationNode AnimationNode { get; set; }

The drop-down menu will be limited to AnimationNode and all its derived classes. Custom resource classes can also be used, see Глобальні класи C#.

Слід зазначити, що навіть якщо скрипт не запущений в редакторі, експортовані властивості можна редагувати. Це може бути використано спільно зі скриптом в режимі "інструмент".

Експорт бітових прапорців

Члени, типом яких є enum з атрибутом [Flags], можна експортувати, а їхні значення обмежуються членами типу enum. Редактор створить віджет в інспекторі, що дозволить не вибрати жодного, одного або кількох членів переліку. Значення буде збережено як ціле число.

У переліку flags використовуються ступені 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;

Ви повинні надати опис рядка для кожного прапора. У цьому прикладі Вогонь має значення 1, Вода має значення 2, Земля має значення 4 і Вітер відповідає значенню 8. Зазвичай константи мають бути визначені відповідно (наприклад, private const int ElementWind = 8 і так далі).

Ви можете додати явні значення за допомогою двокрапки:

[Export(PropertyHint.Flags, "Self:4,Allies:8,Foes:16")]
public int SpellTargets { get; set; } = 0;

Лише значення потужності 2 дійсні як параметри бітових прапорів. Найменше допустиме значення — 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; }

Використання бітових значень вимагає певного розуміння побітових операцій. Якщо ви сумніваєтесь, використовуйте замість них логічні змінні.

Експорт переліків

Члени, типом яких є enum, можна експортувати, а їхні значення обмежуються членами типу enum. Редактор створить віджет в інспекторі, який буде нумерувати наступні елементи як «Thing 1», «Thing 2», «Another Thing». Значення буде збережено як ціле число.

public enum MyEnum
{
    Thing1,
    Thing2,
    AnotherThing = -1,
}

[Export]
public MyEnum MyEnum { get; set; }

Цілі та рядкові члени також можуть бути обмежені певним списком значень за допомогою анотації [Export] з підказкою PropertyHint.Enum. Редактор створить віджет в Інспекторі, у якому буде перераховано такі елементи як Воїн, Маг, Злодій. Значення буде збережено як ціле число, що відповідає індексу вибраного параметра (тобто 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; }

Якщо тип рядок, значення буде збережено як рядок.

[Export(PropertyHint.Enum, "Rebecca,Mary,Leah")]
public string CharacterName { get; set; }

Якщо ви хочете встановити початкове значення, ви повинні вказати його явно:

[Export(PropertyHint.Enum, "Rebecca,Mary,Leah")]
public string CharacterName { get; set; } = "Rebecca";

Exporting inspector buttons with [ExportToolButton]

If you want to create a clickable button in the inspector, you can use the [ExportToolButton] attribute. This exports a Callable property or field as a clickable button. Since this runs in the editor, usage of the [Tool] attribute is required. When the button is pressed, the callable is called:

[Tool]
public partial class MyNode : Node
{
    [ExportToolButton("Click me!")]
    public Callable ClickMeButton => Callable.From(ClickMe);

    public void ClickMe()
    {
        GD.Print("Hello world!");
    }
}

You can also set an icon for the button with a second argument. If specified, an icon will be fetched via GetThemeIcon(), from the "EditorIcons" theme type.

[ExportToolButton("Click me!", Icon = "CharacterBody2D")]
public Callable ClickMeButton => Callable.From(ClickMe);

Експорт колекцій

Як пояснюється в документації C# Variant, тільки певні масиви C# і типи колекцій, визначені в просторі імен Godot.Collections, є сумісними з Variant, тому лише ці типи можна експортувати.

Експорт масивів Годо

[Export]
public Godot.Collections.Array Array { get; set; }

Використання загального Godot.Collections.Array<T> дозволяє вказати тип елементів масиву, які будуть використовуватися як підказка для редактора. Інспектор обмежить елементи вказаним типом.

[Export]
public Godot.Collections.Array<string> Array { get; set; }

Значення за замовчуванням для масивів Годо дорівнює нулю. Можна вказати інше значення за умовчанням:

[Export]
public Godot.Collections.Array<string> CharacterNames { get; set; } =
[
    "Rebecca",
    "Mary",
    "Leah",
];

Масиви з указаними типами, які успадковуються від ресурсу, можна встановити шляхом перетягування кількох файлів із док-станції FileSystem.

[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> дозволяє вказати типи елементів ключа та значення словника.

Примітка

Введені словники наразі не підтримуються в редакторі Godot, тому Inspector не обмежуватиме типи, які можна призначити, що потенційно призведе до винятків під час виконання.

[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# дорівнює null. Можна вказати інше значення за умовчанням:

[Export]
public Vector3[] Vectors { get; set; } =
[
    new Vector3(1, 2, 3),
    new Vector3(3, 2, 1),
];

Встановлення експортованих змінних зі скрипту інструмента

Якщо змінювати значення експортованої змінної зі сценарію в Режим інструмента, значення в інспекторі не оновлюватиметься автоматично. Щоб оновити його, викличте NotifyPropertyListChanged() після встановлення значення експортованої змінної.

Розширений експорт

Не кожен вид експорту можна забезпечити на рівні самої мови, щоб уникнути зайвої складності проєктування. Далі описуються деякі більш-менш загальні функції експорту, які можна реалізувати за допомогою API низького рівня.

Перш ніж читати далі, ви повинні ознайомитись із тим, як обробляються властивості та як їх можна налаштувати за допомогою _Set(), _Get() та :ref:` Методи _GetPropertyList() <class_Object_private_method__get_property_list>`, як описано в Доступ до даних або логіки від об’єкта.

Дивись також

Для прив'язки властивостей, що використовуються в вищезгаданих методах в C++, дивіться Властивості прив’язки за допомогою _set/_get/_get_property_list.

Попередження

Скрипт повинен працювати в режимі tool, щоб вищезазначені методи могли працювати з редактора.