Экспорты GDScript

Введение в экспорт

В Godot, члены класса (переменные и т.д.) могут быть экспортированы. Это означает, что их значение сохраняется вместе с ресурсом (например, сцена), к которому они прикреплены. Они также будут доступны для редактирования редакторе свойств. Экспорт осуществляется с помощью ключевого слова export:

extends Button

export var number = 5 # Value will be saved and visible in the property editor.

Экспортируемая переменная должна быть инициализирована в постоянное выражение (Константу) или иметь подсказку на экспорт в виде аргумента к ключевому слову export (см. ниже секцию Примеры).

Одним из фундаментальных преимуществ экспорта переменных (членов класса) является то, что они видны и редактируются в редакторе. Таким образом, художники и гейм-дизайнеры могут изменять значения, которые впоследствии будут влиять на работу программы. Для этого предусмотрен специальный синтаксис экспорта.

Примечание

Exporting properties can also be done in other languages such as C#. The syntax varies depending on the language.

Примеры

# If the exported value assigns a constant or constant expression,
# the type will be inferred and used in the editor.

export var number = 5

# Export can take a basic data type as an argument, which will be
# used in the editor.

export(int) var number

# Export can also take a resource type to use as a hint.

export(Texture) var character_face
export(PackedScene) var scene_file
# There are many resource types that can be used this way, try e.g.
# the following to list them:
export(Resource) var resource

# Integers and strings hint enumerated values.

# Editor will enumerate as 0, 1 and 2.
export(int, "Warrior", "Magician", "Thief") var character_class
# Editor will enumerate with string names.
export(String, "Rebecca", "Mary", "Leah") var character_name

# Named enum values

# Editor will enumerate as THING_1, THING_2, ANOTHER_THING.
enum NamedEnum {THING_1, THING_2, ANOTHER_THING = -1}
export(NamedEnum) var x

# Strings as paths

# String is a path to a file.
export(String, FILE) var f
# String is a path to a directory.
export(String, DIR) var f
# String is a path to a file, custom filter provided as hint.
export(String, FILE, "*.txt") var f

# Using paths in the global filesystem is also possible,
# but only in scripts in "tool" mode.

# String is a path to a PNG file in the global filesystem.
export(String, FILE, GLOBAL, "*.png") var tool_image
# String is a path to a directory in the global filesystem.
export(String, DIR, GLOBAL) var tool_dir

# The MULTILINE setting tells the editor to show a large input
# field for editing over multiple lines.
export(String, MULTILINE) var text

# Limiting editor input ranges

# Allow integer values from 0 to 20.
export(int, 20) var i
# Allow integer values from -10 to 20.
export(int, -10, 20) var j
# Allow floats from -10 to 20 and snap the value to multiples of 0.2.
export(float, -10, 20, 0.2) var k
# Allow values 'y = exp(x)' where 'y' varies between 100 and 1000
# while snapping to steps of 20. The editor will present a
# slider for easily editing the value.
export(float, EXP, 100, 1000, 20) var l

# Floats with easing hint

# Display a visual representation of the 'ease()' function
# when editing.
export(float, EASE) var transition_speed

# Colors

# Color given as red-green-blue value (alpha will always be 1).
export(Color, RGB) var col
# Color given as red-green-blue-alpha value.
export(Color, RGBA) var col

# Nodes

# Another node in the scene can be exported as a NodePath.
export(NodePath) var node_path
# Do take note that the node itself isn't being exported -
# there is one more step to call the true node:
onready var node = get_node(node_path)

# Resources

export(Resource) var resource
# In the Inspector, you can then drag and drop a resource file
# from the FileSystem dock into the variable slot.

# Opening the inspector dropdown may result in an
# extremely long list of possible classes to create, however.
# Therefore, if you specify an extension of Resource such as:
export(AnimationNode) var resource
# The drop-down menu will be limited to AnimationNode and all
# its inherited classes.

Следует отметить, что даже если во время работы в редакторе скрипт не выполняется, экспортируемые свойства все равно можно редактировать. Это можно использовать в сочетании с режимом "инструмента":.

Экспорт битовых флагов

Целые числа, используемые в качестве битовых флагов, могут хранить несколько true/false (булевых) значений в одном свойстве. Используя подсказку экспорта int, FLAGS, их можно настроить в редакторе:

# Set any of the given flags from the editor.
export(int, FLAGS, "Fire", "Water", "Earth", "Wind") var spell_elements = 0

Вы должны предоставить строчное описание каждому флагу. В этом примере у Fire значение 1, у Water - 2, у Earth - 4 и у Wind - 8. Обычно константы должны быть определены соответствующим образом (например, const ELEMENT_WIND = 8 и так далее).

Подсказки по экспорту также предоставляются для слоев физики и визуализации, определенных в настройках проекта:

export(int, LAYERS_2D_PHYSICS) var layers_2d_physics
export(int, LAYERS_2D_RENDER) var layers_2d_render
export(int, LAYERS_3D_PHYSICS) var layers_3d_physics
export(int, LAYERS_3D_RENDER) var layers_3d_render

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

Экспорт массивов

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

Если экспортируемый массив указывает тип, который наследуется от Ресурса, значения массива можно задать в инспекторе (Inspector), перетаскивая несколько файлов из файловой системы (FileSystem) одновременно.

# Default value must be a constant expression.

export var a = [1, 2, 3]

# Exported arrays can specify type (using the same hints as before).

export(Array, int) var ints = [1, 2, 3]
export(Array, int, "Red", "Green", "Blue") var enums = [2, 1, 0]
export(Array, Array, float) var two_dimensional = [[1.0, 2.0], [3.0, 4.0]]

# You can omit the default value, but then it would be null if not assigned.

export(Array) var b
export(Array, PackedScene) var scenes

# Arrays with specified types which inherit from resource can be set by
# drag-and-dropping multiple files from the FileSystem dock.

export(Array, Texture) var textures
export(Array, PackedScene) var scenes

# Typed arrays also work, only initialized empty:

export var vector3s = PoolVector3Array()
export var strings = PoolStringArray()

# Default value can include run-time values, but can't
# be exported.

var c = [a, 2, 3]

Установка экспортированных переменных из скрипта инструмента

При изменении значения экспортируемой переменной из скрипта в Режим Инструмента значение в Инспекторе (Inspector) не будет обновляться автоматически. Чтобы обновить его, вызовите property_list_changed_notify() после установки значения экспортируемой переменной.

Расширенный экспорт

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

Прежде чем читать дальше, вы должны ознакомиться с тем, как свойства обрабатываются и как они могут быть настроены с помощью методов _set(), _get(), and _get_property_list(), описанных в разделе Доступ к данным или логике из объекта.

См.также

Свойства привязки, использующие описанные выше методы в C++, см. в разделе Связывание свойств через _set/_get/_get_property_list.

Предупреждение

Скрипт должен работать в режиме tool, чтобы вышеперечисленные методы могли работать из редактора.

Свойства

To understand how to better use the sections below, you should understand how to make properties with advanced exports.

func _get_property_list():
    var properties = []
    # Same as "export(int) var my_property"
    properties.append({
        name = "my_property",
        type = TYPE_INT
    })
    return properties
  • The _get_property_list() function gets called by the inspector. You can override it for more advanced exports. You must return an Array with the contents of the properties for the function to work.

  • name это имя свойства

  • type is the type of the property from Variant.Type.

Примечание

The float type is called a real (TYPE_REAL) in the Variant.Type enum.

Присоединение переменных к свойствам

To attach variables to properties (allowing the value of the property to be used in scripts), you need to create a variable with the exact same name as the property or else you may need to override the _set() and _get() methods. Attaching a variable to to a property also gives you the ability to give it a default state.

# This variable is determined by the function below.
# This variable acts just like a regular gdscript export.
var my_property = 5

func _get_property_list():
    var properties = []
    # Same as "export(int) var my_property"
    properties.append({
        name = "my_property",
        type = TYPE_INT
    })
    return properties

Добавление значений по умолчанию для свойств

To define default values for advanced exports, you need to override the property_can_revert() and property_get_revert() methods.

  • The property_can_revert() method takes the name of a property and must return true if the property can be reverted. This will enable the Revert button next to the property in the inspector.

  • The property_get_revert() method takes the name of a property and must return the default value for that property.

func _get_property_list():
    var properties = []
    properties.append({
        name = "my_property",
        type = TYPE_INT
    })
    return properties

func property_can_revert(property):
    if property == "my_property":
        return true
    return false

func property_get_revert(property):
    if property == "my_property":
        return 5

Добавление категорий скриптов

Для лучшего визуального различения свойств в инспектор можно внедрить специальную категорию скрипта, которая будет действовать как разделитель. Script Variables (переменные скрипта) — это один из примеров встроенной категории.

func _get_property_list():
    var properties = []
    properties.append({
        name = "Debug",
        type = TYPE_NIL,
        usage = PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_SCRIPT_VARIABLE
    })

    # Example of adding a property to the script category
    properties.append({
        name = "Logging_Enabled",
        type = TYPE_BOOL
    })
    return properties
  • name это название категории, которая будет добавлена в инспектор;

  • Every following property added after the category definition will be a part of the category.

  • PROPERTY_USAGE_CATEGORY указывает, что свойство должно рассматриваться именно как категория скрипта, поэтому тип TYPE_NIL можно игнорировать, поскольку он фактически не будет использоваться для логики скрипта, но все равно должен быть определен.

Свойства группировки

Список свойств с похожими именами можно сгруппировать.

func _get_property_list():
    var properties = []
    properties.append({
        name = "Rotate",
        type = TYPE_NIL,
        hint_string = "rotate_",
        usage = PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SCRIPT_VARIABLE
    })

    # Example of adding to the group
    properties.append({
        name = "rotate_speed",
        type = TYPE_REAL
    })

    # This property won't get added to the group
    # due to not having the "rotate_" prefix.
    properties.append({
        name = "trail_color",
        type = TYPE_COLOR
    })
    return properties
  • name - это имя группы, которая будет отображаться в виде складываемого списка свойств;

  • Every following property added after the group property with the prefix (which determined by hint_string) will be shortened. For instance, rotate_speed is going to be shortened to speed in this case. However, movement_speed won't be a part of the group and will not be shortened.

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