Введение: от ключевых слов к аннотациям

В Godot 4 несколько ключевых слов GDScript были заменены аннотациями с префиксом @. Это было частью более крупной работы по тому, чтобы сделать синтаксис GDScript чище и последовательнее. Три самых важных изменения:

  • export@export
  • onready@onready
  • tool@tool

Аннотации размещаются на строке перед объявлением, которое они модифицируют (или на той же строке). В Godot 4 также появилось множество новых вариантов аннотаций, таких как @export_range, @export_group и @export_category, которых не было в Godot 3. Это руководство охватывает их все.

Базовый @export

Аннотация @export делает переменную видимой в инспекторе Godot, позволяя настраивать значения без редактирования кода. Godot автоматически выбирает подходящий виджет редактора на основе типа переменной.

GDScript
@export var speed: float = 300.0
@export var player_name: String = "Player"
@export var health: int = 100
@export var color: Color = Color.WHITE
@export var texture: Texture2D
@export var scene: PackedScene

Совет: Всегда добавляйте аннотации типов к экспортируемым переменным. Это гарантирует, что инспектор покажет правильный виджет (например, палитру цветов для Color, слот ресурса для Texture2D).

@export_range — числовые ползунки

@export_range ограничивает числовое значение минимумом и максимумом, отображая ползунок в инспекторе. Также можно задать размер шага и подсказки вроде "or_greater" или "or_less".

GDScript
@export_range(0, 100) var health: int = 100
@export_range(0.0, 1.0, 0.01) var volume: float = 0.8
@export_range(0, 1000, 1, "or_greater") var damage: int = 10

Подсказка "or_greater" позволяет вводить значения выше максимума, сохраняя при этом сфокусированный диапазон ползунка. Аналогично, "or_less" разрешает значения ниже минимума.

@export_enum — выпадающие меню

@export_enum создаёт выпадающий список в инспекторе. При использовании с String сохраняется имя выбранной опции. При использовании с int можно назначать явные значения.

GDScript
# Stores the string name: "Warrior", "Mage", or "Rogue"
@export_enum("Warrior", "Mage", "Rogue") var character_class: String

# Stores the integer value: 0, 1, or 2
@export_enum("Easy:0", "Normal:1", "Hard:2") var difficulty: int = 1

@export_file и @export_dir — пути к файлам/каталогам

@export_file отображает диалог выбора файла в инспекторе. Можно фильтровать по расширению файла. @export_dir отображает диалог выбора каталога.

GDScript
@export_file("*.tscn") var next_level: String
@export_dir var save_directory: String

Строка фильтра использует glob-шаблоны. Несколько фильтров можно разделять запятыми: "*.png,*.jpg".

@export_multiline и @export_placeholder

@export_multiline предоставляет большую текстовую область для многострочных строк (отлично подходит для диалогов или описаний). @export_placeholder показывает текст-подсказку внутри поля, когда оно пустое.

GDScript
@export_multiline var description: String
@export_placeholder("Enter name...") var player_name: String

@export_group и @export_subgroup — организация свойств в инспекторе

@export_group создаёт сворачиваемый заголовок группы в инспекторе. Все следующие за ним переменные @export принадлежат этой группе — до следующей группы или категории. @export_subgroup вкладывается внутрь текущей группы.

GDScript
@export_group("Movement")
@export var speed: float = 300.0
@export var jump_force: float = 400.0

@export_group("Combat")
@export var attack_damage: int = 10
@export var defense: int = 5

@export_subgroup("Ranged")
@export var projectile_speed: float = 500.0

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

@export_category — жирные заголовки категорий

@export_category создаёт жирный заголовок категории верхнего уровня в инспекторе. В отличие от групп, категории нельзя сворачивать, и они выступают как сильный визуальный разделитель между несвязанными наборами свойств.

GDScript
@export_category("Player Stats")
@export var level: int = 1
@export var experience: int = 0

@export со ссылками на ноды

Можно экспортировать NodePath, чтобы дизайнеры могли выбрать ноду из дерева сцены. В Godot 4.2+ можно экспортировать типизированную ссылку на ноду напрямую — без NodePath.

GDScript
# Classic NodePath export
@export var target_path: NodePath

# Godot 4.2+: typed node export (direct reference, no NodePath needed)
@export var sprite: Sprite2D
@export var collision: CollisionShape2D

Типизированные экспорты нод — рекомендуемый подход в современном Godot 4. Инспектор показывает выбор нод, отфильтрованный по указанному типу, а в редакторе скриптов вы получаете полное автодополнение.

@export_flags — флажки битовой маски

@export_flags создаёт набор флажков, где каждая опция соответствует биту в целом числе. Godot также предоставляет встроенные экспорты флагов для физических и рендер-слоёв.

GDScript
# Custom flags: Fire=1, Water=2, Earth=4, Wind=8
@export_flags("Fire", "Water", "Earth", "Wind") var elements: int

# Built-in physics layer flags
@export_flags_2d_physics var collision_layers: int
@export_flags_2d_render var render_layers: int
@export_flags_3d_physics var collision_layers_3d: int

@onready — отложенная инициализация

@onready откладывает инициализацию переменной до момента, когда нода входит в дерево сцены (эквивалентно присваиванию в _ready()). Это необходимо при обращении к дочерним нодам через $, поскольку дочерние ноды недоступны на этапе разбора.

GDScript
# Godot 3 (old syntax):
# onready var sprite = $Sprite2D

# Godot 4:
@onready var sprite: Sprite2D = $Sprite2D
@onready var anim: AnimationPlayer = $AnimationPlayer
@onready var label: Label = $UI/ScoreLabel

Лучшая практика: Всегда типизируйте свои переменные @onready. Это включает автодополнение и позволяет ловить ошибки типов на этапе разбора, а не во время выполнения.

@tool — запуск скриптов в редакторе

@tool заставляет скрипт выполняться внутри редактора Godot (не только во время выполнения). Это мощный инструмент для создания собственных предпросмотров, гизмо и свойств, обновляемых в реальном времени. Размещайте его в самом верху скрипта, перед extends.

GDScript
@tool
extends Node2D

@export var radius: float = 100.0:
    set(value):
        radius = value
        queue_redraw()  # Redraw in editor when value changes

func _draw() -> void:
    draw_circle(Vector2.ZERO, radius, Color.WHITE)

Предупреждение: Будьте осторожны со скриптами @tool. Код в _process() и _physics_process() будет выполняться в редакторе. Используйте Engine.is_editor_hint(), чтобы защитить логику, предназначенную только для игры.

Другие аннотации

@icon

Задаёт пользовательскую иконку для типа ноды скрипта в доке сцены и диалоге «Создать ноду».

GDScript
@icon("res://icons/enemy.svg")
extends CharacterBody2D

@warning_ignore

Подавляет определённые предупреждения GDScript для следующего оператора. Полезно, когда вы намеренно затеняете переменную или имеете неиспользуемый параметр.

GDScript
@warning_ignore("unused_parameter")
func _on_body_entered(body: Node2D) -> void:
    queue_free()

@warning_ignore("shadowed_variable")
var size: int = 10

@static_unload

Помечает скрипт так, чтобы Godot мог выгрузить его из памяти, когда не существует ни одного экземпляра. Это может снизить потребление памяти для скриптов, которые используются лишь временно. Скрипт не должен иметь статических переменных или данных, которые необходимо сохранять.

GDScript
@static_unload
extends RefCounted

# This script can be safely unloaded when not in use

Лучшие практики статической типизации

Хотя это и не аннотации, статические подсказки типов тесно с ними связаны и настоятельно рекомендуются в Godot 4. Они улучшают автодополнение, включают проверку ошибок на этапе компиляции и могут повысить производительность.

GDScript
# Variable type annotations
var speed: float = 300.0
var player: CharacterBody2D = null
var items: Array[String] = []
var scores: Dictionary = {}

# Function return types and parameter types
func get_damage() -> int:
    return attack - defense

func apply_force(direction: Vector2, strength: float) -> void:
    velocity += direction * strength

# Type inference with :=
var pos := Vector2(100, 200)  # Inferred as Vector2

Примечание: Будьте осторожны с := в циклах for при итерации по нетипизированным массивам. Вместо этого используйте явные аннотации типов: for item: String in array.

Шпаргалка по миграции: Godot 3 на 4

Краткий справочник по преобразованию синтаксиса экспорта Godot 3 в аннотации Godot 4:

Godot 3 Godot 4 Примечания
export var x @export var x Базовый экспорт
export(int, 0, 100) var hp @export_range(0, 100) var hp: int Диапазон с подсказкой типа
export(String, "A", "B") var x @export_enum("A", "B") var x: String Выпадающий список enum
export(String, FILE) var path @export_file var path: String Выбор файла
export(String, MULTILINE) var text @export_multiline var text: String Многострочная текстовая область
export(int, FLAGS, ...) var f @export_flags(...) var f: int Флаги битовой маски
onready var x = $Node @onready var x: Type = $Node Отложенная инициализация
tool @tool Выполнение в редакторе
Недоступно @export_group("...") Новое в Godot 4
Недоступно @export_category("...") Новое в Godot 4
Недоступно @export_subgroup("...") Новое в Godot 4

Godot MCP Pro понимает все аннотации @export

Godot MCP Pro может создавать скрипты с правильно типизированными экспортами, читать и изменять существующие аннотации экспорта и инспектировать экспортированные свойства любой ноды в вашей сцене — всё через ИИ.

  • create_script
  • edit_script
  • read_script
  • get_node_properties
  • get_scene_exports
  • update_property
Получить Godot MCP Pro — $15