Manuals
Manuals




This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English

Defold для користувачів Unity

Якщо у вас уже є досвід роботи з Unity, цей посібник допоможе швидко почати продуктивно працювати в Defold. Він зосереджується на найважливішому та скеровує до офіційних посібників Defold, коли потрібні докладніші відомості.

Вступ

Defold — цілком безкоштовний, справді кросплатформний ігровий 3D-рушій із редактором для Windows, Linux і macOS. Повний вихідний код доступний на Github.

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

Defold значно менший за Unity. Розмір рушія з порожнім проєктом на всіх платформах становить 1–3 МБ. Ви можете вилучити додаткові частини рушія та перенести частину вмісту гри до Live Update, щоб завантажувати її окремо пізніше. Порівняння розмірів та інші причини обрати Defold наведено на сторінці «Чому Defold».

Щоб пристосувати Defold до своїх потреб, ви можете створити власні або використати наявні:

  1. Повністю керований скриптами конвеєр рендерингу (скрипт рендерингу + матеріали/шейдери) з кількома графічними API на вибір (OpenGL, Vulkan тощо).
  2. Код і компоненти (components) у вигляді нативних розширень (C++/C#).
  3. Скрипти редактора та віджети інтерфейсу для налаштування редактора.
  4. Змінену збірку рушія та редактора, оскільки доступні повний вихідний код і конвеєр збирання.

Також радимо переглянути відео Game From Scratch про Defold для розробників Unity.


Установлення

  1. Завантажте Defold для своєї ОС.
  2. Розпакуйте та запустіть його.

Ось і все. Жодного хаба, установлення додаткових SDK, наборів інструментів чи пакетів для платформ. Саме тому ми кажемо, що Defold не потребує налаштування.

Якщо потрібні докладніші відомості, прочитайте цей короткий посібник зі встановлення.

Версії

Defold часто оновлюється й не має гілки «LTS». Ми радимо завжди використовувати найновішу версію. Нові версії виходять регулярно — зазвичай щомісяця, після приблизно двох тижнів відкритого бета-тестування. Ви можете оновити Defold безпосередньо в редакторі.


Екран привітання

Defold зустрічає вас екраном привітання, подібним до Unity Hub, де можна відкрити нещодавні проєкти:

Порівняння екранів привітання

Або створити новий на основі:

  • Templates — базових порожніх проєктів для швидшого налаштування під певну платформу чи жанр,
  • Tutorials — покрокових уроків, які допоможуть зробити перші кроки,
  • Samples — офіційних або створених спільнотою прикладів і варіантів використання,

Порівняння шаблонів на екрані привітання

Коли ви створите свій перший проєкт і/або відкриєте його, він відкриється в редакторі Defold.

Привіт, світе

Це простий спосіб швидко зробити щось у Defold: виконайте ці кроки, а потім поверніться до решти посібника.

  1. Виберіть порожній проєкт у Templates, укажіть його назву в Title, виберіть розташування та створіть його, натиснувши Create New Project. Він відкриється в редакторі Defold. Привіт, світе: крок 1
  2. Ліворуч, на панелі Assets, відкрийте теку main і двічі клацніть main.collection, щоб відкрити цей файл.
  3. Праворуч, на панелі Outline, клацніть правою кнопкою миші Collection і виберіть Add Game Object. Привіт, світе: крок 2
  4. Клацніть правою кнопкою миші створений ігровий об’єкт (game object) go і виберіть Add Component, а потім Label. Привіт, світе: крок 3
  5. Унизу ліворуч, на панелі Properties, уведіть щось у властивість Text.
  6. У головній центральній області перегляду сцени перетягніть напис приблизно в позицію (480,320,0) або змініть її в Properties: Position. Привіт, світе: крок 4
  7. Змінивши позицію напису, збережіть проєкт, вибравши File -> Save All або натиснувши Ctrl+S (Cmd+S на Mac).
  8. Зберіть проєкт, вибравши Project -> Build або натиснувши Ctrl+B (Cmd+B на Mac). Привіт, світе: крок 5

Ви щойно зібрали свій перший проєкт у Defold і маєте побачити свій текст у вікні. Поняття ігрового об’єкта та компонента мають бути вам знайомі. Нижче пояснено колекції (collections), панелі Outline і Properties та причину, з якої нам потрібно було трохи перемістити напис угору й праворуч.


Огляд редактора Defold

Тут ми розглянемо редактор Defold з погляду того, що користувач Unity, імовірно, захоче дізнатися насамперед, але радимо потім ознайомитися з повним посібником з огляду редактора.

Порівняння редакторів

Перша відмінність, яку ви помітите між Unity та Defold, — стандартне компонування редактора. Ми показуємо редактор Unity зі злегка зміненим компонуванням, щоб воно відповідало стандартному компонуванню Defold. Редактори розміщено поруч, щоб було легше візуально порівняти основні панелі, адже вкладки Unity вам має бути простіше впізнати.

Порівняння редакторів

За замовчуванням редактор Defold відкривається з ортографічним попереднім переглядом у 2D. Якщо ви працюватимете над 3D-проєктом або просто хочете отримати досвід, ближчий до Unity, — радимо перейти з 2D у 3D, вимкнувши перемикач 2D на панелі інструментів, і змінити проєкцію камери на перспективну, увімкнувши перемикач Perspective:

Панель інструментів Defold

Також можна змінити Grid Settings на панелі інструментів, щоб використовувати площину Y, як у Unity:

Налаштування 3D у Defold

Огляд панелей Defold

Редактор Defold поділено на 6 основних панелей.

Редактор 2

Нижче наведено порівняння назв у Defold і відмінностей у функціональності:

Defold Unity Відмінності
1. Assets Project (Assets Browser) У Defold панель Assets закріплено ліворуч. Defold не створює файлів meta.
2. Main Editor Scene View Редактор Defold залежить від контексту (різні редактори для різних типів файлів), тоді як Unity використовує окремі спеціалізовані вікна (наприклад, Animator, Shader Graph). Defold також має вбудований редактор коду.
3. Outline Hierarchy Defold показує лише поточний відкритий файл або вибраний елемент (ігровий об’єкт чи компонент), а не глобальну ієрархію.
4. Properties Inspector Defold показує лише властивості поточного вибраного елемента в Outline, а не всіх компонентів ігрового об’єкта.
5. Tools Console Defold надає інструменти у вкладках Console, Curve Editor, Build Errors, Search Results, Breakpoints і Debugger.
6. Changed Files Unity Version Control (Plastic) У Defold після інтеграції Git у проєкт тут відображаються змінені файли. Ви також можете користуватися Git зовнішніми засобами.

Інші корисні назви, пов’язані з редактором:

Defold Unity Відмінності
Game Build Game Preview Показує запущену гру, зібрану рушієм. Defold може запускати кілька екземплярів (instances) гри з редактора, подібно до Multiplayer Play Mode у Unity 6+. У Defold гра завжди працює в окремому, незакріпленому вікні. Defold також може запускати гру на зовнішньому пристрої (наприклад, мобільному телефоні), подібно до Unity Remote.
Вкладки Вкладки Defold дає змогу редагувати вміст поруч у двох панелях області Main Editor. Вкладки й панелі закріплено в одному вікні редактора; видимість панелей можна перемикати (F6, F7, F8), а їхні розміри — змінювати.
Панель інструментів Toolbar / Scene View Options Лише в новіших версіях Unity інструменти трансформації перенесено до області перегляду сцени, подібно до Defold.
Console Console Панель Console у Defold не можна відкріпити. Помилки збирання в Defold з’являються в окремій вкладці Build Errors.
Build Errors Помилки компіляції в Console Скрипти Lua інтерпретуються, тому помилок компіляції немає. Проте ваш проєкт збирається, і під час збирання можуть виникати певні помилки. Defold також використовує Lua Language Server для статичного аналізу скриптів.
Search Results Search / Project Search У Defold немає фільтрування за типами й мітками.
Curve Editor Unity Curve Editor Curve Editor у Defold дає змогу редагувати криві лише для властивостей ефектів частинок.
Налагоджувач Visual Studio Debugger Налагоджувач повністю інтегровано в Defold відразу після встановлення. Є додаткова вкладка для відстеження, увімкнення та вимкнення точок зупину.

Ключові поняття

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

Будівельні блоки

Defold оперує лише кількома основними будівельними блоками:

Будівельні блоки

Докладніше читайте в повному посібнику про будівельні блоки Defold.

Ігрові об’єкти

Defold використовує «ігрові об’єкти», подібно до Unity. В обох рушіях ігрові об’єкти — це контейнери даних з ідентифікатором, і всі вони мають трансформації: позицію, поворот і масштаб. Проте в Defold трансформація вбудована, а не є окремим компонентом.

Ви можете створювати батьківсько-дочірні зв’язки між ігровими об’єктами. У Defold це можна робити лише в редакторі всередині «колекції» (пояснено нижче) або динамічно в скрипті. Ігрові об’єкти не можуть містити інші ігрові об’єкти як вкладені об’єкти так, як це можливо в Unity.

Компоненти

В обох рушіях ігрові об’єкти можна розширювати за допомогою «компонентів». Defold надає мінімальний набір основних компонентів. Відмінностей між 2D і 3D тут менше, ніж у Unity (наприклад, для колайдерів), тому компонентів загалом менше, а деяких компонентів Unity вам може бракувати.

Компоненти поведінки

У Unity «компонент» зазвичай означає MonoBehaviour, прикріплений до GameObject. Ви можете створювати власні компоненти, успадковуючи MonoBehaviour, або використовувати вбудовані, як-от Light, різні фізичні компоненти тощо.

У Defold компонент — це виключно те, що приблизно відповідає вбудованим компонентам Unity, проте Defold не розглядає скрипт як MonoBehaviour і не вимагає жодного явного «позначення», щоб прикріпити його до ігрового об’єкта, окрім створення обробників подій/зворотних викликів.

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

Докладніше читайте про компоненти Defold тут.

У таблиці нижче наведено подібні компоненти Unity для швидкого зіставлення та посилання на посібник для кожного компонента Defold:

Defold Unity Відмінності
Спрайт Sprite Renderer У Defold відтінок (властивість кольору) можна змінювати лише через код.
Карта плиток Tilemap / Grid Defold має вбудований редактор карт плиток, який підтримує квадратні сітки (але є розширення, наприклад, для шестикутників), і не має вбудованих правил автоматичного розміщення плиток. Інструменти на кшталт Tiled, TileSetter чи Sprite Fusion підтримують експорт у Defold.
Напис Text / TextMeshPro Defold має розширення RichText для розширеного форматування (подібно до TextMeshPro).
Звук AudioSource У Defold є лише глобальне джерело звуку (не просторове). Для Defold є офіційне розширення FMOD.
Фабрика Prefab Instantiate() У Defold фабрика (factory) — це компонент із певним прототипом (префабом).
Фабрика колекції - (Немає прямого відповідника компонента) Компонент-фабрика колекції в Defold може одночасно створювати кілька ігрових об’єктів із батьківсько-дочірніми зв’язками.
Об’єкт колізій Rigidbody + Collider У Defold фізичні об’єкти та форми колізій поєднано в одному компоненті.
Форми колізій BoxCollider / SphereCollider / CapsuleCollider У Defold форми (паралелепіпед, сфера, капсула) налаштовують усередині компонента Collision Object. Обидва рушії підтримують форми колізій із карт плиток і даних опуклих оболонок.
Камера Camera У Unity камера має дещо більше вбудованих налаштувань рендерингу й постобробки, тоді як Defold передає це користувачеві для власного керування через скрипт рендерингу.
GUI UI Toolkit / Unity UI / uGUI Canvas GUI у Defold — потужний компонент для створення повноцінних інтерфейсів і шаблонів. Unity не має подібного єдиного компонента інтерфейсу, натомість пропонує кілька фреймворків для інтерфейсів. Defold також має розширення для розширення.
Скрипт GUI Скрипти Unity UI / uGUI GUI у Defold можна керувати через скрипти GUI за допомогою спеціалізованого API gui.
Модель MeshRenderer + Material У Defold компонент Model поєднує файл 3D-моделі, текстури та матеріал із шейдерами.
Меш MeshRenderer / MeshFilter / Процедурний меш У Defold Mesh — це компонент для керування набором вершин через код. Він подібний до Model у Defold, але ще більш низькорівневий.
Ефект частинок Particle System Редактор частинок Defold підтримує 2D/3D-ефекти частинок із багатьма властивостями й дає змогу анімувати їх у часі за допомогою кривих у Curve Editor. Він не підтримує сліди чи колізії.
Скрипт Script Відмінності в програмуванні докладніше пояснено нижче.

Розширення та власні компоненти

Defold також має офіційні компоненти Spine і Rive, доступні через розширення.

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

Деякі компоненти Unity не мають готового відповідника в Defold, наприклад Audio Listener, Light, Terrain, LineRenderer, TrailRenderer, Cloth чи Animator. Проте всю цю функціональність можна реалізувати в скриптах, і вже є готові рішення: наприклад, різні конвеєри освітлення, компонент Mesh для генерування довільних мешів (зокрема рельєфу) або Hyper Trails для налаштовуваних ефектів слідів. У майбутньому Defold також може отримати нові вбудовані компоненти, наприклад джерела світла.

Ресурси

Деякі компоненти потребують «ресурсів», як і в Unity: наприклад, спрайтам і моделям потрібні текстури. Деякі з них порівняно в таблиці нижче:

Defold Unity Відмінності
Атлас Sprite Atlas / Texture2D Defold також має розширення для Texture Packer.
Джерело плиток Tile Palette + Ресурс У Defold джерело плиток можна використовувати як текстуру для карт плиток, а також для спрайтів чи частинок.
Шрифт Font Використовується компонентом Label у Defold або текстовими вузлами GUI, подібно до Text/TextMeshPro у Unity.
Матеріал Material У Defold шейдери називаються вершинною програмою та фрагментною програмою.

Колекція та сцена

У Defold ігрові об’єкти та компоненти можна розміщувати в окремих файлах, як префаби Unity, або визначати у файлі «колекції», який їх об’єднує.

Колекція в Defold — це, по суті, текстовий файл зі статичним описом сцени. Це не об’єкт середовища виконання. Вона лише визначає, які ігрові об’єкти слід створити в грі та як установити батьківсько-дочірні зв’язки між ними.

Ігрові світи

Сцени Unity за замовчуванням мають спільні глобальний стан гри й фізичну симуляцію, фактично той самий світ (ігровий світ). У Defold є два варіанти:

  1. Створити ігрові об’єкти з файлу окремого ігрового об’єкта через Factory або з файлу колекції через Collection Factory у заданому, вже створеному світі, як префаби.
  2. Створити окремий ігровий світ під час виконання, з власними ігровими об’єктами, фізичним світом, операціями рушія та простором імен для адресації, через колекцію, завантажену під час запуску, або через компонент Collection Proxy — проксі колекції (collection proxy).

Фабрики та компоненти проксі також пояснено нижче. Докладніше про колекції читайте в посібнику про будівельні блоки.


Ресурси та вміст проєкту

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

Ресурси проєкту

Unity зберігає ресурси в Assets/ і генерує файли .meta. У Defold немає метафайлів. Проєкт у Defold — це просто структура ваших тек, точно як на диску, і панель Assets завжди її відображає.

Формати ресурсів

Unity імпортує ресурси та непомітно для користувача перетворює їх на інші формати. У Defold ви працюєте безпосередньо з вихідними ресурсами (.png, .gltf, .wav, .ogg тощо) і призначаєте їх компонентам Components.

Unity може використовувати окреме зображення як спрайт. У Defold зображення можна використовувати безпосередньо для моделей/мешів, але спрайти/GUI/карти плиток/частинки потребують атласу (упакованих текстур) або джерела плиток (плиток на основі сітки).

Більшість ресурсів Defold зберігаються як текст, що зручно для систем контролю версій.

Кеш бібліотеки

Unity генерує теку Library/ для імпортованих ресурсів. У Defold такого каталогу немає; ресурси обробляються під час збирання, а кешовані результати зберігаються в теці збирання (і в необов’язкових локальних/віддалених кешах збирання).


Написання коду

Відповідником скриптів MonoBehaviour у Defold є компонент Script, але є кілька відмінностей, про які варто знати.

Lua

Скрипти Defold пишуть багатопарадигмовою мовою Lua з динамічною типізацією.

Є кілька типів скриптів Lua: *.script, *.gui_script, *.render_script, *.editor_script, а також модулі *.lua.

Teal

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

Нативні розширення на C++/C#

Нативні розширення Defold можна писати кількома іншими мовами: C, C++, C#, Objective-C, Java чи JS залежно від цільової платформи. Якщо ви добре володієте C#, технічно можливо організувати більшу частину ігрової логіки в розширенні на C# і просто викликати її з невеликого стартового скрипту Lua, хоча це потребує поглибленого знання API й не рекомендовано початківцям.

Докладніше про розширення читайте в посібнику з нативних розширень Defold.

Від MonoBehaviour до модулів Lua

Unity має відкриту модель написання скриптів. Оскільки MonoBehaviour — основний спосіб додавання поведінки в редакторі, багато проєктів Unity починаються з одного скрипту-контролера на кожен важливий GameObject: PlayerController, EnemyController, BulletController, GameManager, EnemyManager тощо.

Defold конкретніше визначає свою стандартну архітектуру. Ігровий об’єкт може мати .script, але вам рідко потрібно створювати скрипт для кожного ігрового об’єкта: завдяки потужним засобам адресації та передавання повідомлень Defold один скрипт може керувати сотнями чи тисячами інших об’єктів та їхніх компонентів, навіть якщо ті взагалі не мають власних скриптів. Створювати окремий скрипт для кожного ігрового об’єкта потрібно рідко, і це може призвести до зайвого ускладнення.

Для повторно використовуваної ігрової поведінки розробники Unity часто переходять до композиції: менших скриптів MonoBehaviour, як-от Health.cs, Attack.cs чи EnemyFinder.cs, прикріплених до одного GameObject. У Defold зазвичай залишають один прикріплений .script як головний скрипт або координатор, а повторно використовувану логіку розміщують у звичайних модулях Lua.

У Unity така композиція може виглядати так:

Player
├── PlayerMovement.cs
├── PlayerAttack.cs
├── EnemyFinder.cs
└── Health.cs

У Defold ті самі обов’язки часто розподіляють між одним прикріпленим скриптом і повторно використовуваними модулями:

player.go
├── sprite
├── collisionobject
└── player.script

modules/
├── player_movement.lua
├── player_attack.lua
├── enemy_finder.lua
└── health.lua

Прикріплений .script стає головним скриптом або координатором. Модулі Lua містять повторно використовувану логіку, подібно до того, як невеликі скрипти MonoBehaviour у Unity часто відповідають за щось одне.

local movement = require "modules.player_movement"
local attack = require "modules.player_attack"
local finder = require "modules.enemy_finder"
local health = require "modules.health"

function init(self)
    self.movement = movement.new(self)
    self.attack = attack.new(self)
    self.finder = finder.new(self)
    self.health = health.new(self)
end

function update(self, dt)
    self.movement:update(dt)
    self.attack:update(dt)
    self.finder:update(dt)
end

function on_message(self, message_id, message, sender)
    self.health:on_message(message_id, message, sender)
    self.attack:on_message(message_id, message, sender)
end

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

Unity Defold
Прикріпіть кілька скриптів MonoBehaviour в Inspector Прикріпіть один .script і поєднайте модулі Lua в коді
Використовуйте GetComponent<T>() або серіалізовані поля для зв’язування поведінок Зберігайте екземпляри модулів у self і використовуйте адреси/повідомлення між об’єктами
Кожен компонент може мати власні методи життєвого циклу Головний скрипт скеровує виклики init(), update(), on_message(), final() тощо
Можливі різні архітектурні стилі Поширена практика — явна композиція коду, орієнтована на повідомлення

Спочатку це може бути незвично, особливо якщо ви звикли налаштовувати поведінку, додаючи компоненти в Inspector. У Defold багато з того, що ви могли б налаштовувати візуально в Unity, натомість можна створювати, зв’язувати, вмикати, вимикати чи оновлювати через код. Система повідомлень Defold допомагає зменшити зв’язність логіки: відправник надсилає дані за адресою, а отримувач вирішує, що з ними робити.

Хоча цей підхід рекомендовано, він не є обов’язковим, і ви можете писати скрипти як завгодно, зокрема прикріплювати кілька скриптів до одного ігрового об’єкта або наближатися до об’єктно-орієнтованого стилю програмування. Є навіть бібліотеки, які допоможуть у цьому (defold-oop або lua-class).

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

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

Корисні посібники з написання коду:

Вбудований редактор коду

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

Редактор коду Defold

VS Code та інші редактори

За бажанням ви можете використовувати власний зовнішній редактор. Усі компоненти Defold і пов’язані файли є текстовими, тож їх можна редагувати будь-яким текстовим редактором, але потрібно дотримуватися належного форматування та структури елементів, оскільки вони базуються на Protobuf.

Якщо ви звикли до VS Code і хочете писати в ньому код гри, радимо встановити Defold Kit або Defold Buddy із Visual Studio Marketplace.

Ви також можете змінити налаштування редактора Defold, щоб текстові файли за замовчуванням відкривалися у VS Code (або будь-якому іншому зовнішньому редакторі). Подробиці дивіться в налаштуваннях редактора.

Шейдери — GLSL

Defold використовує GLSL (OpenGL Shading Language) для шейдерів — Vertex Programs і Fragment Programs, подібно до Unity. Хоча Defold не пропонує Shader Graph, як Unity (що може бути недоліком), ви все одно можете створювати рівноцінні шейдери, пишучи код.

Докладніше про шейдери читайте в посібнику з шейдерів.

Матеріали

Defold використовує поняття Material, що поєднує шейдери .fp і .vp, семплери (текстури) та інші елементи, як-от атрибути вершин (Vertex Attributes) або константи (Constants).

Докладніше про матеріали читайте в посібнику з матеріалів.


Система повідомлень

У Defold об’єкти не зберігають прямих посилань один на одного. Тут немає GetComponent, викликів методів між скриптами різних об’єктів чи глобального доступу до сцени, як у Unity.

Натомість скрипти взаємодіють через передавання повідомлень: ви надсилаєте повідомлення іншим скриптам, замість виклику методів або прямого доступу до компонентів. Що ці об’єкти робитимуть із повідомленнями, вирішують вони самі.

Спочатку це може бути незвично, але такий підхід сприяє слабкій зв’язності та зменшує тісні взаємозалежності.

Надсилання повідомлення

У Unity взаємодія зазвичай виглядає так:

var enemy = GameObject.Find("Enemy");
enemy.GetComponent<EnemyAI>().TakeDamage(10);

Тобто об’єкти можуть безпосередньо посилатися один на одного та викликати методи інших скриптів. Усе існує в одному спільному просторі сцени.

У Defold ви надсилаєте повідомлення з одного скрипту іншому скрипту (або іншому компоненту):

msg.post("#my_component", "my_message", { my_name = "Defold" })

І можете обробляти ці повідомлення в скрипті:

function on_message(self, message_id, messsage)
    if message_id == hash("my_message") then
        print("Hello ", message.my_name)
    end
end

Поки що не зважайте на # і hash, ми повернемося до них пізніше. Решта має бути зрозумілою. Ви можете надіслати повідомлення будь-якому компоненту (навіть тому самому скрипту) будь-якого створеного ігрового об’єкта.

Компоненти, відмінні від скриптів

Іноді ви надсилаєте повідомлення, наприклад, компонентам Sprite чи Collision, щоб увімкнути або вимкнути їх. Іноді компоненти Components надсилають повідомлення вашому скрипту, наприклад, коли виникає колізія, щоб ви могли її обробити. Defold внутрішньо використовує ту саму систему повідомлень для подій рушія та ігрової взаємодії.

Система повідомлень дещо подібна до SendMessage або систем подій Unity, хоча адресація й усталені підходи відрізняються.

Докладніше читайте в посібнику з передавання повідомлень.

Адресація

Об’єкти та компоненти в Defold визначаються адресами, відомими як URL.

Кожен створений об’єкт і компонент має власну унікальну адресу, і для їх пошуку не потрібно обходити граф сцени. Це робить адресацію явною та прямою.

Простий URL у Defold може виглядати так:

"/player"

Це концептуально подібне до:

GameObject.Find("player")

Тепер час пояснити, чому в адресах використовувалися "/" або "#".

URL у Defold (подібно до URL) складається з трьох частин:

socket: /path #fragment

Або, якщо описати це термінами Defold:

collection: /gameobject #component 

Пробіли в цих описах додано лише для візуального розділення трьох частин.

Отже, простими словами:

  1. collection: визначає контекст колекції, з : наприкінці.
  2. /path визначає ігровий об’єкт, з / перед ідентифікатором.
  3. #fragment визначає конкретний компонент цього об’єкта (наприклад, скрипт, спрайт або компонент колізій), з # перед ідентифікатором.

Статична адреса

Ці ідентифікатори визначаються під час створення кожного елемента й ніколи не змінюються, навіть якщо ви змінюєте батьківсько-дочірні зв’язки. Ви можете задати їх у властивості Id у файлах або отримати під час виконання з викликів factory.create чи collectionfactory.create під час створення екземплярів.

Відносна адресація

Вам не завжди потрібно використовувати повний URL.

Якщо ви надсилаєте повідомлення в межах однієї колекції (того самого світу), можна опустити частину сокета:

/gameobject #component

Якщо ви надсилаєте повідомлення компоненту в межах того самого ігрового об’єкта, можна також опустити частину ігрового об’єкта:

#component

Два корисні скорочення:

  • # для надсилання цьому компоненту Script
  • . для надсилання всім компонентам цього ігрового об’єкта

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

Надсилання повідомлень до GUI та рендерингу

Оскільки Defold відокремлює світ GUI від світу ігрових об’єктів, ви також можете надсилати повідомлення зі скриптів ігрових об’єктів .scripts до .gui_scripts.

Ви також можете надсилати повідомлення до спеціальних системних просторів імен за допомогою ідентифікатора, що починається з @. Наприклад, до системи рендерингу можна звернутися через @render: і використати це для керування певними вбудованими можливостями рендерингу, як-от зміною проєкції у стандартному скрипті рендерингу:

msg.post("@render:", "use_stretch_projection", { near = -1, far = 1 })

Докладніше читайте в посібнику з адресації.


Префаби та екземпляри

Unity може створювати екземпляри будь-чого в сцені статично або динамічно, і Defold може робити те саме. У Unity ви берете префаб і викликаєте Instantiate(prefab). У Defold є 3 компоненти для створення екземплярів вмісту:

  • Factory — створює екземпляр одного ігрового об’єкта із заданого прототипу: файлу *.go (префабу).
  • Collection Factory — створює екземпляри набору ігрових об’єктів із батьківсько-дочірніми зв’язками із заданого прототипу: файлу *.collection.
  • Collection Proxyзавантажує та створює новий світ із файлу *.collection.

Фабрика

Коли ви визначили компонент Factory, указавши відповідний файл ігрового об’єкта у властивості Prototype, створити екземпляр можна простим викликом у коді:

factory.create("#my_factory")

Тут використовується адреса компонента, у цьому випадку — відносний шлях з ідентифікатором "#my_factory".

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

local new_instance_id = factory.create("#my_factory")

Пам’ятайте, що в Defold не потрібно вручну керувати пулом об’єктів — рушій сам робить це внутрішньо за вас.

Докладніше читайте в посібнику з фабрик.

Фабрика колекції

Відмінність між компонентами Factory і Collection Factory полягає в тому, що фабрика колекції може одночасно створювати кілька ігрових об’єктів і під час створення встановлювати батьківсько-дочірні зв’язки, визначені у файлі *.collection.

У Unity такого поділу немає: він не має окремого поняття, яке відповідає фабриці колекції Defold. Найближчий аналог — просто вкладений префаб, що містить ієрархію об’єктів.

Виклик повертає таблицю з ідентифікаторами всіх створених екземплярів:

local spawned_instances = collectionfactory.create("#my_collectionfactory")

Докладніше читайте в посібнику з фабрик колекцій.

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

Під час виклику factory.create() або collectionfactory.create() ви також можете вказати необов’язкові параметри, як-от позицію, поворот, масштаб і властивості скрипту, щоб точно контролювати, як і де з’явиться екземпляр та як він поводитиметься, наприклад:

local scale_2d = vmath.vector3(0.5, 0.5, 1.0)
factory.create("#my_factory", my_position, my_rotation, my_properties, scale_2d)

Порядок необов’язкових аргументів: спочатку властивості, потім масштаб. Якщо ви масштабуєте 2D-об’єкт лише за осями X і Y, використовуйте vector3, явно задавши Z значення 1.0; числовий масштаб застосовується однаково до всіх трьох осей.

Динамічне завантаження

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

Докладніше читайте в посібнику з керування ресурсами.

Проксі колекції

Collection Proxy посилається на певний файл *.collection, але замість додавання об’єктів до поточного світу (як це роблять фабрики) він завантажує та створює новий ігровий світ. Це дещо подібне до завантаження цілої сцени в Unity, але з суворішим відокремленням.

У Unity ви могли б завантажити додаткову сцену так:

SceneManager.LoadSceneAsync("Level2", LoadSceneMode.Additive);

У Defold ви завантажуєте нову колекцію, просто надіславши повідомлення компоненту Collection Proxy:

msg.post("#myproxy", "load")
  1. Коли ви надсилаєте проксі повідомлення "load" (або "async_load" для асинхронного завантаження), рушій виділяє новий світ, створює в ньому екземпляри всього вмісту цієї колекції та тримає його ізольованим.
  2. Після завантаження проксі надсилає у відповідь повідомлення "proxy_loaded", яке означає, що світ готовий.
  3. Потім ви зазвичай надсилаєте повідомлення "init" і "enable", щоб об’єкти в новому світі почали свій звичайний життєвий цикл.

Для взаємодії між завантаженими світами потрібно явно передавати повідомлення за URL, що містять назву світу (collection:, перша частина URL).

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

Якщо ви колись використовували кілька сцен у Unity та потребували, щоб вони поводилися незалежно, сприймайте Collection Proxy як спосіб перенести це поняття безпосередньо до Defold.

Докладніше читайте в посібнику з проксі колекції.


Життєвий цикл застосунку

Ви знайомі з набором подій життєвого циклу Unity: Awake, Start, Update, FixedUpdate, LateUpdate, OnDestroy або OnApplicationQuit.

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

Ось порівняння:

Defold Unity Коментар
init() Awake() / Start() / OnEnable() Defold має єдину точку входу та зворотний виклик для ініціалізації — init(). Він викликається для кожного компонента під час його створення.
on_input Методи введення Defold отримує введення, коли скрипт отримав фокус введення. Обробляється першим у циклі оновлення.
fixed_update() FixedUpdate() Викликається з фіксованим кроком часу. Щоб увімкнути його в Defold, потрібно встановити Use Fixed Timestepподробиці. Починаючи з версії 1.12.0, виконується перед update().
update() Update() Викликається один раз на кадр із дельтою часу.
late_update() LateUpdate() Викликається після update(), безпосередньо перед рендерингом кадру. Доступний із версії 1.12.0.
on_message Отримувач повідомлень Основний зворотний виклик Defold для отримання повідомлень. Обробляється, коли в черзі є будь-яке повідомлення.
final OnDisable / OnDestroy / OnApplicationQuit Defold викликає final() для кожного компонента, коли його ігровий об’єкт знищується під час виконання (за допомогою go.delete()) або коли вивантажується світ/колекція, а під час завершення застосунку — для всіх об’єктів, що залишилися.

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

Ініціалізація

Сприймайте init() у Defold як поєднання елементів Awake(), Start() і OnEnable() у Unity в єдиній точці входу, де рушій уже все налаштував і ви можете безпечно підготувати стан компонента.

Коли обробляються повідомлення?

Оскільки ви вже можете надсилати повідомлення в init(), уперше вони доставляються відразу після ініціалізації.

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

Цикл оновлення

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

Завершення

У Defold очищення завжди пов’язане з видаленням або вивантаженням світу, а єдиний обробник завершення для кожного компонента — final().

Тонка відмінність від моделі Unity полягає в тому, що немає розрізнення між вимкненням компонента та завершенням усього застосунку.

Рендеринг

Скрипт рендерингу (*.render_script) — це частина конвеєра рендерингу, яка також бере участь у життєвому циклі з власними зворотними викликами init(), update() і on_message(), але вони працюють у потоці рендерингу та відокремлені від логіки скриптів ігрових об’єктів і GUI.

Докладніше читайте в посібнику з життєвого циклу застосунку.


GUI

GUI у Defold — це єдиний цілісний спеціалізований фреймворк для інтерфейсів користувача: меню, накладених елементів, діалогів тощо, подібний до UI Toolkit або uGUI з Canvas.

GUI — це компонент, відокремлений від ігрових об’єктів і колекцій. Замість ігрових об’єктів ви працюєте з вузлами GUI, організованими в ієрархію, якими керує скрипт GUI.

Вузли GUI

Коли ви відкриваєте файл компонента *.gui у Defold, перед вами з’являється полотно, на якому ви розміщуєте вузли "GUI nodes". Це будівельні блоки GUI. Ви можете додавати вузли GUI таких типів:

  • Box (прямокутна форма з текстурою)
  • Text (із будь-яким шрифтом)
  • Pie (елемент у формі сектора круга з радіальним заповненням і текстурою)
  • ParticleFX
  • Template (інший цілий вкладений файл .gui, наче префаб GUI)
  • а також вузол Spine, якщо використовується розширення Spine.

Скрипт GUI

Компонент GUI має спеціальну властивість для скриптів GUI: ви призначаєте один файл *.gui_script на компонент, і він дає змогу змінювати його поведінку. Отже, він дуже подібний до звичайних скриптів, але не використовує простір імен go.* (призначений для скриптів ігрових об’єктів). Натомість він використовує спеціальний API простору імен gui.*, який працює лише всередині скриптів GUI (*.gui_script). Ви можете уявляти це як окрему сцену. Unity UI (uGUI) з Canvas.

Рендеринг GUI

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

Докладніше читайте в посібнику з GUI.

Де шари сортування?

Це дуже поширене джерело непорозумінь під час переходу з Unity.

Компоненти GUI мають Layers, і це працює майже так само, як «Sorting Layers» у Unity, але для інших компонентів, як-от Sprites, Tilemaps, Models тощо, прямого відповідника немає.

Натомість ви зазвичай поєднуєте:

  • Точне впорядкування за віссю Z, коли використовується стандартна камера, або за глибиною, коли використовується компонент Camera.
  • Загальне впорядкування через скрипт рендерингу за допомогою предикатів рендерингу — для вибору того, що малювати, за тегами матеріалів.

Але не варто відтворювати Sorting Layers із Unity за допомогою великої кількості тегів, оскільки в Defold теги — це механізм рівня рендерингу. Надмірне використання тегів може порушити групування викликів малювання та збільшити накладні витрати на малювання.


Куди рухатися далі?

Якщо у вас є запитання або виникли труднощі, форум Defold чи Discord — чудові місця, де можна звернутися по допомогу.