Ноды и Терминология

Прежде чем продолжить, следует отметить, что термин Node ("Узел") необходимо использовать с осторожностью. При ссылке на Visual Script Nodes ("Узлы Визуального Скрипта") (или вообще Nodes ("Узлы")) этот текст будет ссылаться на маленькие прямоугольники, которые вы соединяете линиями и которые являются частью графа. При ссылке на Scene Nodes ("Узлы Сцены") подразумевается, что мы ссылаемся на элементы, составляющие Сцену, которые являются частью дерева узлов. Их имена похожи, но функциональность разная. При ссылке на Node ("Узел") здесь подразумевается ссылка на Visual Script Node ("Узлы Визуального Скрипта"), если не указано иное.

../../../_images/visual_script16.png

Свойства узла

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

Узлы по-прежнему отображают необходимую информацию в виде текста, но редактирование выполняется с помощью Inspector. Чтобы редактировать их, выберите любой узел и отредактируйте его свойства в Inspector.

Порты и соединения

Программирование в Godot Visual Scripting происходит через Nodes и Port Connections внутри каждой функции.

Порты

Узлы в Godot Visual Scripting имеют Ports (Порты). Это конечные точки, которые появляются слева и справа от узлов, которые можно использовать для создания Connections*(Соединений): существует два типа *Ports (Портов): Sequence (Последовательность) и Data (Данные).

../../../_images/visual_script17.png

Sequence Ports ("Последовательные порты") указывают порядок, в котором выполняются операции. Как правило, когда Node ("Узел") завершает обработку, он переходит к следующему узлу через один из портов справа. Если к узлу ничего не подключено, функция может завершиться, или может быть выбран другой выход Sequence Port ("Последовательного порта") (это зависит от узла). Благодаря этому вы можете следить за логикой внутри функции, следуя по белым линиям. Не каждый Node ("Узел") имеет Sequence Ports ("Последовательные порты"). На самом деле в большинстве случаев их нет.

Data Ports ("Порты данных") содержат типизированные данные. Типы могут быть любыми обычными типами Godot, такими как булево, целое число, строка, Vector3, массив, любой Объект или Узел Сцены и т.п. Data Ports ("Порты данных") на правой стороне узла считается выходом, а порт на левой стороне - входом. Соединение с ним позволяет передавать информацию на следующий узел.

Однако не все типы Data Port ("Порты данных") совместимы и разрешают соединения. Обратите особое внимание на цвета и значки, так как каждый тип имеет свое представление:

../../../_images/visual_script18.png

Соединения

Подключение является относительно простым процессом. Перетащите Output Port ("Выходной порт") к Input Port ("Входному порту").

../../../_images/visual_script_connect.gif

Отключение требует немного больше практики. Отключение Data Ports ("Портов данных") происходит путем перетаскивания к Input (ко "Входу"), напротив, отключение Sequence Ports ("Последовательных портов") происходит путем перетаскивания к Output (к "Выходу").

../../../_images/visual_script_disconnect.gif

Поначалу это может показаться странным, но это происходит потому, что Data Ports ("Порты данных") подключаются по схеме 1:N (один порт вывода может быть соединен с несколькими входами), в то время как Sequence Ports ("Последовательные порты") подключаются по схеме N:1 (много последовательных выходов могут быть соединены с одним входом).

Подключение к пустому пространству (перетаскивание линии соединения на пустое место без нажатия) является также контекстно зависимым, оно предоставит список наиболее распространенных операций:

../../../_images/visual_script52.png

Соответственно для данных откроется контекстное меню установки/получения/вызова:

../../../_images/visual_script53.png

Создание узлов

И в заключении! Мы получили самое интересное! Но прежде чем объяснять более подробно, что делает каждый тип узла, давайте кратко рассмотрим, как наиболее часто добавляются и обрабатываются узлы.

Доступ к узлам сцены

Одной из наиболее распространенных задач является доступ к узлам дерева сцен (опять же, не путать с Visual Script Nodes ("Узлами Визуального Скрипта")). Перетаскивание узла из дерева сцен на канву попросит вас вызвать метод (иногда называемый функцией-членом) в этом узле.

../../../_images/visual_script19.png

Хотя доступ к свойствам желателен в большинстве случаев (подробнее об этом ниже), иногда также может быть полезен вызов методов. Методы выполняют определенные действия над объектами. Другим распространенным вариантом использования является постановка узла в очередь для удаления, что осуществляется с помощью метода queue_free.

../../../_images/visual_script20.png

Необходимо убедиться, что это работает, только если редактируемая сцена содержит ваш Visual Script ("Визуальный скрипт") в одном из узлов! В противном случае будет показано предупреждение.

Доступ к свойствам узлов сцены

Это наиболее распространенный способ редактирования Узлов Сцены в визуальных сценариях. Выберите Scene Node ("Узел сцены") из Scene Tree ("Дерева сцены"), перейдите к Инспектору, найдите Имя свойства, которое вы хотите редактировать (подсказку, не значение!) и перетащите его на холст:

../../../_images/visual_script21.png

В результате это значение может быть изменено из вашего сценария путем записи в Data Port ("Порт данных").

Если вместо этого требуется чтение этого значения, перетащите узел еще раз, но удерживайте клавишу Ctrl (или:kbd:Cmd на macOS). Это создаст "производитель"("getter"):

../../../_images/visual_script22.png

В этом случае значение может быть прочитано из Data Port ("Порта данных").

Переменные

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

Чтобы добавить переменную, нажмите кнопку «+» в секции Variables ("Переменные") пользовательской панели. Дважды кликните на новой переменной, чтобы переименовать ее:

../../../_images/visual_script23.png

Щелчок правой кнопкой мыши по переменной позволяет настроить ее свойства:

../../../_images/visual_script24.png ../../../_images/visual_script25.png

Как было показано выше, можно изменить тип и начальное значение переменной, а также некоторые ее свойства. Отметка «Экспорт» делает эту переменную видимой в Инспекторе при выборе узла. Это также делает ее доступной для других сценариев с помощью метода, описанного в предыдущем шаге.

../../../_images/visual_script28.png

Чтобы использовать переменную в скрипте, просто перетащите ее на канву, чтобы создать геттер:

../../../_images/visual_script26.png

Аналогично, удерживайте Ctrl (или Cmd на macOS), чтобы получился сеттер:

../../../_images/visual_script27.png

Сигналы

Также возможно создавать свои собственные сигналы в скрипте и использовать их. Для этого выполните те же шаги, что и для переменных на предыдущем шаге, но для Signals:

../../../_images/visual_script29.png

Сигнал также может быть отредактирован через контекстное меню, позволяющее настроить его аргументы:

../../../_images/visual_script30.png

Созданный вами сигнал появится в Инспекторе вместе с встроенными сигналами узла. Это позволит вам подключить его из другого скрипта другого Scene Node ("Узла сцены"):

../../../_images/visual_script31.png

Наконец, чтобы отправить сигнал, просто перетащите его на холст:

../../../_images/visual_script32.png

Помните, что отправка сигнала - это последовательная операция, поэтому он должен поступать из последовательного порта.

Добавление дополнительных узлов

Теперь, когда основы описаны, давайте обсудим большое количество вспомогательных узлов, доступных для вашего холста! Под панелью элементов существует список всех доступных типов узлов:

../../../_images/visual_script33.png

Нажатие Ctrl + F ( или Cmd + F на macOS) позволит осуществить поиск в списке.

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

../../../_images/visual_script34.png

Помните, что вы можете проверить ссылку на класс на предмет того, что делает каждый узел, так как они там задокументированы. Тем не менее, краткий обзор типов узлов приведен ниже:

Константы

Constant узлы - это узлы предоставляющие значения, которые, не изменяясь во времени, могут быть полезны в качестве эталонных значений. Чаще всего они целочисленные или с плавающей запятой.

../../../_images/visual_script36.png

Первым из них является постоянный узел «Константа», который позволяет вам выбрать любое значение любого типа в качестве константы, от целого числа (42) до строки («Привет!»). В большинстве случаев этот узел используется не часто из-за входных значений по умолчанию в Data Ports (Портах данных), но хорошим тоном будет знать, что он существует.

Вторым является постоянный узел GlobalConstant (Глобальная Константа), который содержит длинный список констант для глобальных типов в Godot. Там вы можете найти несколько полезных констант для обозначения имен клавиш, джойстика или кнопок мыши и т.п.

Третьим постоянным узлом является MathConstant (МатематическаяКонстанта), который предоставляет типичные математические константы, такие как число PI, E и т.д.

Данные

Узлы данных имеют дело со всеми видами доступа к информации. Любая информация в Godot доступна через эти узлы, поэтому они являются одними из самых важных для использования и довольно разнообразными.

../../../_images/visual_script37.png

Среди них есть много интересующих нас типов узлов, поэтому далее последует попытка коротко их описать:

Действие

Узлы действий жизненно важны при вводе с устройства. Вы сможете больше прочитать о действиях в (@TODO ACTION TUTE LINK). В примере, приведенном ниже, элемент управления перемещается вправо при нажатии действия «move_right» (переместить_вправо).

../../../_images/visual_script38.png

Синглтон движка

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

../../../_images/visual_script39.png

Запомните, что перемещение связанных ключей в пустую область поможет вам вызвать функцию или set/get свойства:

../../../_images/visual_script40.png

Локальные Переменные

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

../../../_images/visual_script41.png

Как видно выше, доступны два узла: простой геттер и последовательный геттер (для настройки требуется последовательный порт).

Узлы Сцены

Это просто ссылка на узел в дереве, но проще использовать этот узел, перетаскивая фактический узел из дерева сцены на холст (это создаст его и настроит).

Субъект

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

Дерево сцены

Этот узел схож с узлом Singleton потому что он ссылается на SceneTree, который хранит активные сцены. SceneTree, тем не менее, работает только когда этот узел находится в сцене в активном состоянии, иначе же при обращении возникнет ошибка.

SceneTree допускает множество низкоуровневых вещей, таких как установка параметров растяжения, вызов групп, создание таймеров или даже загрузка другой сцены. Это хороший класс для знакомства.

Предварительная загрузка

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

Путь к ресурсу

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

Комментарий

Узел Комментарий работает как узел, размер которого можно изменить, чтобы разместить вокруг других узлов. Он не будет пытаться стать текущим или оказаться самым верхним при его выборе. Он также может быть использован для написания текста на нем.

../../../_images/visual_script42.png

Управление потоком

Узлы контроля потоков позволяют разделение выполнения кода на различные ветви, обычно зависящее от выполнения каких-либо условий.

../../../_images/visual_script43.png

Условие

Это простой узел, который проверяет булевый (bool) порт. Если условие выполняется (истина), он будет проходить через «истинный» (первый) последовательный порт. В противном случае - через второй. После перехода к любому из них он проходит через «done» (работающий) порт. Оставлять последовательные порты отключенными - это нормально, если не все из них используются.

Итератор

Некоторые типы данных в Godot (то есть массивы, словари) являются итеративными (их элементы можно перебирать в цикле). Это означает, что немного кода может выполняться для каждого элемента, из которых объект такого типа состоит.

Узел Итератор проходит через все элементы и, для каждого из них, он проходит через «каждый» последовательный порт, делая элемент доступным в порте данных «elem».

Когда это сделано, он проходит через последовательный порт "Выход".

Возвращение

Некоторые функции могут возвращать значения. В общем случае для виртуальных функций Godot будет добавлять для вас узел Возврата (Return). Узел Возврата (Return) принудительно завершает функцию.

Последовательность

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

TypeCast

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

../../../_images/visual_script55.png

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

../../../_images/visual_script54.png

Переключатель

Узел Переключатель аналогичен узлу Условие, но он проверяет совпадение со многими значениями одновременно.

Пока

Это более примитивная форма итерации. Вывод последовательности «repeat» будет вызываться, пока не выполнится условие в порте данных «cond».

Функции

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

Встроенный

Существует целый ряд встроенных вспомогательных функций. Они почти идентичны тем, что используются в GDScript. Большинство из них представляют из себя математические функции, но другие могут быть полезными помощниками. Обязательно взгляните на них когда-нибудь.

По типу

Это методы, доступные для базовых типов. Например, если вам нужен dot-product вектора, ищите "dot" вместо того, чтобы искать в категории Vector3. В большинстве случаев просто ищите список узлом, так должно быть быстрее.

Вызов

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

Конструкторы

Это все функции необходимые для создания базовых типов данных Godot. Например, если вам нужно создать Vector3 из трех float, должен использоваться конструктор.

../../../_images/visual_script44.png

Деструктор

Это противоположность Конструктору, которая позволяет разделить любой основной тип (например, Vector3) на его под-элементы.

../../../_images/visual_script45.png

Испускание сигнала

Издает сигналы от любого объекта. В общем, это не так полезно, так как перетаскивание сигнала на canvas работает лучше.

Получать/Задавать

Общий узел получения/установки. Перетаскивание свойств из Инспектора работает лучше, так как они выглядят правильно настроенными при перетаскивании.

Ожидать

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

Yield

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

Yield Signal

То же, что и Yield, но будет ждать, пока данный сигнал не будет испущен.

Индекс

Общий оператор индексирования, используется не часто, но он существует, на всякий случай.

Операторы

Это в основном общие операторы, такие как сложение, умножение, сравнение и т.д. По умолчанию, они принимают в принципе любой тип данных (и будут бросать ошибку во время выполнения, если подаваемые типы не соответствуют ожиданиям оператора). Всегда рекомендуется выбирать правильный тип, чтобы операторы быстрее улавливали ошибки и облегчали чтение графа.

../../../_images/visual_script46.png

Узел Выражения

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

Узлы выражений могут:

  • Выполнить математические и логические вычисления на основе пользовательских входных данных (например, «a * 5 + b», где a и b - пользовательские входные данные):

../../../_images/visual_script47.png
  • Доступ к локальным переменным или свойствам:

../../../_images/visual_script48.png
  • Используйте множество встроенных функций, доступных для GDScript, таких как sin(), cos(), print(), а также конструкторы, такие как Vector3(x, y, z), Rect2(...) , и так далее:

../../../_images/visual_script49.png
  • Вызов API функций:

../../../_images/visual_script50.png
  • Используйте последовательный режим, который имеет больше смысла в случае соблюдения порядка обработки:

../../../_images/visual_script51.png