Скриптинґ

Вступ

До Godot 3.0 для написання скриптів гри можна було використовувати тільки GDScript. На сьогоднішній день у Godot є чотири (так, чотири!) офіційних мови та можливість додавати додаткові мови скриптів!

Це чудово, головним чином завдяки великій гнучкості, але це також ускладнює нашу роботу щодо підтримки мов.

«Головними» мовами в Godot, однак, є GDScript і VisualScript. Основною причиною їх вибору є рівень їх інтеграції з Godot; обоє мають інтеграцію в редакторі, тоді як C # та C ++ потрібно редагувати в окремому IDE. Якщо ви є великим шанувальником мов статичного типу, використовуйте C # та C ++.

GDScript

Як згадувалося вище, GDScript є основною мовою, що використовується в Godot. Використання його має деякі позитивні моменти порівняно з іншими мовами через високу інтеграцію з Godot:

  • Він простий, елегантний та розроблений так, щоби бути знайомим для користувачів інших мов, таких як Lua, Python, Squirrel тощо.
  • Завантажує і компілює надзвичайно швидко.
  • Інтеграція з редактором дозволяє із задоволенням писати код для вузлів, сигналів та багатьох інших елементів, що стосуються сцени, яка редагується.
  • Має вбудовані векторні типи (наприклад, Вектори, перетворення тощо), що робить його ефективним для використання лінійної алгебри.
  • Підтримує декілька потоків так само ефективно, як і статичні мови - одне з обмежень, яке змусило нас уникати таких машин, як Lua, Squirrel тощо.
  • Не використовує прибиральник сміття, тому він торгує (trades) невеликим шматочком автоматизації (більшість об’єктів все одно рахуються по посиланнях), детермінізмом.
  • Його динамічний характер дозволяє легко оптимізувати розділи коду в C ++ (за допомогою GDNative), якщо потрібна більша продуктивність, все без перекомпіляції двигуна.

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

VisualScript

Починаючи з 3.0, Godot пропонує Visual Scripting. Це типова реалізація мови «блоків та з’єднань», але адаптована до роботи Godot.

Visual scripting - це чудовий інструмент для не програмістів, та і для досвідчених розробників, які хочуть зробити частини коду більш доступними для інших, наприклад, дизайнерів ігор, або художників.

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

.NET / C#

Оскільки Microsoft C# є улюбленою серед розробників ігор, ми додали офіційну підтримку для неї. C# - це зріла мова, на якій написано багато кодів, і підтримка була додана завдяки щедрій пожертві Microsoft.

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

Оскільки Godot використовує середовище Mono .NET, теоретично будь-яка стороння бібліотека .NET, або фреймворк, може використовуватися для написання скриптів у Godot, а також будь-яка мова програмування, сумісна з загальною мовною інфраструктурою, наприклад F#, Boo, або ClojureCLR. На практиці, однак, C# - єдиний офіційно підтримуваний варіант .NET.

GDNative / C++

Нарешті, одне з наших найяскравіших доповнень до версії 3.0: GDNative дозволяє створювати скрипти на C ++, не потребуючи перекомпіляції (або навіть перезавантаження) Godot.

Може бути використана будь-яка версія C++, прекрасно працює змішування брендів та версій компілятора для створення спільних бібліотек, завдяки нашому використанню внутрішнього моста C API.

Ця мова є найкращим вибором для продуктивності, і її не потрібно використовувати у всій грі, оскільки інші частини можуть бути написані в GDScript, або Visual Script. Однак API зрозумілий і простий у використанні, оскільки він нагадує, в основному, фактичний API C++ Godot.

Більше мов можна отримати через інтерфейс GDNative, але майте на увазі, що у нас немає офіційної підтримки для них.

Написання скриптів сцени

В решті цього уроку ми створимо графічний інтерфейс, що складається з кнопки та мітки, де натискання кнопки оновить мітку. Ми розглянемо:

  • Написання скрипту та приєднання його до вузла.
  • Підключення елементів інтерфейсу через сигнали.
  • Написання скрипту, який може отримати доступ до інших вузлів сцени.

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

Налаштування сцени

Використовуйте діалогове вікно «Додати дочірній вузол», доступ до якого здійснюється на панелі Сцена (або натисканням Ctrl+A), щоб створити ієрархію з такими вузлами:

  • Панель
    • Мітка
    • Кнопка

Дерево сцени має виглядати так:

../../_images/scripting_scene_tree.png

Використовуйте 2D-редактор для розміщення та зміни розміру кнопки та мітки так, щоб вони виглядали як на зображенні нижче. Ви можете встановити текст на панелі «Інспектор».

../../_images/label_button_example.png

Нарешті, збережіть сцену під назвою sayhello.tscn.

Додавання скрипту

Клацніть правою кнопкою миші на вузлі Panel (Панель), а потім виберіть «Долучити скрипт» у спадному меню:

../../_images/add_script.png

З’явиться діалогове вікно створення скрипту. Це діалогове вікно дозволяє встановити мову скрипту, назву класу та інші відповідні параметри.

У GDScript сам файл представляє клас, тому поле імені класу не можна редагувати.

Вузол, до якого ми приєднуємо скрипт, - це панель, тому поле «Успадковує» автоматично буде вписано «Panel». Цього ми і хочемо, оскільки мета скрипту - розширити функціональність нашого панельного вузла.

Нарешті, введіть назву шляху до скрипту та натисніть Створити:

../../_images/script_create.png

Скрипт буде створений і доданий до вузла. Ви можете бачити його, як значок «Відкрити скрипт» поруч із вузлом на вкладці Сцена, а також у властивості скрипт в Інспекторі:

../../_images/script_added.png

Щоб відредагувати скрипт, виберіть будь-яку з цих кнопок, обидві вони виділені на зображенні вище. Це відкриє для вас редактор скриптів, де буде створений шаблон за замовчуванням:

../../_images/script_template.png

Там не так багато. Функція _ready() викликається , коли вузол, і всі його нащадки, входять в активну сцену. Примітка: _ready() не є конструктором; конструктором є _init().

Роль скрипту

Скрипт додає до вузла поведінку. Він використовується для управління функціональністю вузла та його взаємодією з іншими вузлами: нащадками, предками, братами і сестрами тощо. Локальна область дії скрипту - вузол. Іншими словами, скрипт успадковує функції, надані цим вузлом.

../../_images/brainslug.jpg

Обробка сигналу

Сигнали «випромінюються», коли відбувається певний вид дії, і їх можна підключити до будь-якої функції будь-якого екземпляра скрипту. Сигнали використовуються здебільшого у вузлах GUI, хоча інші вузли їх також мають, і ви навіть можете визначити власні сигнали у власних скриптах.

На цьому кроці ми підключимо сигнал «pressed» («натиснуто») до власної функції. Формування з’єднань - перша частина, а визначення власної функції - друга частина. У першій частині Godot надає два способи створення з’єднань: через візуальний інтерфейс, який надає редактор, або через код.

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

Виберіть вузол Button (Кнопка) в дереві сцени, а потім виберіть вкладку «Вузол». Далі переконайтесь, що вибрано “Сигнали”.

../../_images/signals.png

Якщо ви виберете «pressed()» під «BaseButton» і натиснете кнопку «Підключити …» в нижньому правому куті, ви відкриєте діалог створення з’єднання.

../../_images/connect_dialogue.png

У верхній частині діалогового вікна є список вузлів вашої сцени, синім кольором виділене ім’я вузла, що випромінює сигнал. Тут виберіть вузол «Panel».

У нижній частині діалогового вікна вказана назва методу, який буде створено. За замовчуванням ім’я методу буде містити ім’я вузла, що випромінює сигнал (у цьому випадку «Button» («Кнопка»)), в результаті виходить _on_[ВипромінюючийВузол]_[назва_сигналу].

І цим закінчується урок про використання візуального інтерфейсу. Однак заради навчання давайте зануримось у ручний процес!

Для цього ми познайомимося з функцією, яку, мабуть, найбільше використовують програмісти Godot:Node.get_node(). Ця функція використовує шляхи для отримання вузлів у будь-якій точці сцени, відносно вузла, якому належить скрипт.

Для зручності видаліть усе, що знаходиться під extends Panel. Ви заповните решту частину скрипту вручну.

Оскільки Button (кнопка) та Label (мітка) обоє нащадки Panel (панелі), якій додається скрипт, ви можете отримати кнопку, ввівши в функції _ready() наступне :

func _ready():
    get_node("Button")
public override void _Ready()
{
    GetNode("Button");
}

Далі напишіть функцію, яка буде викликана при натисканні кнопки:

func _on_Button_pressed():
    get_node("Label").text = "HELLO!"
public void _OnButtonPressed()
{
    GetNode<Label>("Label").Text = "HELLO!";
}

Нарешті, підключіть сигнал кнопки «pressed» (натиснуто) до _on_Button_pressed(), використовуючи Object.connect().

func _ready():
    get_node("Button").connect("pressed", self, "_on_Button_pressed")
public override void _Ready()
{
    GetNode("Button").Connect("pressed", this, nameof(_OnButtonPressed));
}

Врешті скрипт повинен виглядати так:

extends Panel

func _ready():
    get_node("Button").connect("pressed", self, "_on_Button_pressed")

func _on_Button_pressed():
    get_node("Label").text = "HELLO!"
using Godot;

// IMPORTANT: the name of the class MUST match the filename exactly.
// this is case sensitive!
public class sayhello : Panel
{
    public override void _Ready()
    {
        GetNode("Button").Connect("pressed", this, nameof(_OnButtonPressed));
    }

    public void _OnButtonPressed()
    {
        GetNode<Label>("Label").Text = "HELLO!";
    }
}

Запустіть сцену і натисніть кнопку. Ви повинні отримати такий результат:

../../_images/scripting_hello.png

Вітаємо вас із написанням скрипту до вашої першої сцени.

Примітка

Багато-хто з цього уроку не може зрозуміти, як працює get_node(path). Для заданого вузла get_node(path) шукає своїх безпосередніх нащадків. У наведеному вище коді це означає, що Button (Кнопка) повинна бути нащадком Panel (Панелі). Якби Кнопка була нащадком Label (Мітки), кодом для її отримання було б:

# Not for this case,
# but just in case.
get_node("Label/Button")
// Not for this case,
// but just in case.
GetNode("Label/Button")

Також пам’ятайте, що вузли посилаються на назву, а не тип.

Примітка

Права панель діалогу підключення призначена для прив’язки конкретних значень до параметрів підключеної функції. Можна додавати та вилучати значення різних типів.

В коді це можна реалізувати за допомогою 4-го Array параметра, який за замовчуванням порожній. Для отримання додаткової інформації можете почитати про метод Object.connect.