Візуальне програмування. Як створити зручний та якісний алгоритм

Привіт! Мене звати Андрій Крупський, я Middle UE Developer y Pingle Game Studio. У цій статті я хотів би поговорити про візуальне програмування, його основні переваги перед звичайним програмуванням, а також детальніше зупинитися на роботі з блупринтами.

Що таке візуальне програмування

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

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

Існує багато візуальних мов програмування. Не всі знайшли свою аудиторію. Ряд з них створювався як графічні додатки до своїх програм — від бортових комп’ютерів до ігрових рушіїв. App Inventor — одна з таких мов, вона допомогала в розробці додатків для Android.

Інший приклад — мова Scratch.

Декілька років тому, до того як потрапити в геймдев, я займався навчанням дітей програмуванню. І робив це якраз через Scratch. До речі, основна ідея створення цієї мови полягає саме в навчанні дітей програмуванню. З дітьми у нас були різні роботи, зроблені з Arduino. Завдяки графічним блокам, свою програму учні могли запустити вже за декілька секунд після написання. Зазвичай, їх код виглядав так: Коли ми починаємо програму — ми рухаємось вперед, якщо лівий датчик кольору побачить чорний колір — ми трохи повертаємо вправо, і навпаки. Таким чином, наш робот міг рухатись по лабіринту, межі якого були оброблені чорною стрічкою. Потім писали свої контролери, аби управляти роботами за допомогою пульта дистанційного керування.

Тут відео з тих часів:

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

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

Blueprints в Unreal Engine

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

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

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

Потенційно можна створити гру повністю на блупринтах. На моїй першій роботі в геймдеві це так і було: за два роки розробки ми з нуля створили онлайнову МОВА гру у віртуальній реальності. Наша команда складалася з 4 людей, і тільки один програміст з команди мав великий досвід у програмуванні на С++. Однак за цей час ми створили гру, яка повністю функціонувала на блупринтах, працювала в майже стабільних 90 FPS у грі 5 проти 5 (реальних гравців).

Чи це правильний підхід до створення гри? Навряд. За два роки ми декілька разів піднімали питання про перенесення хоча б частини логіки у С++. Але як це часто трапляється, строки постійно переносилися. Ми завжди казали, що «зараз проведемо виставку і перенесемо на С++», після цього «ну в нас скоро буде тест, то треба пофіксити баги, а потім будемо переносити на плюси» і тому подібне. Так пройшло 2 роки, ми релізнули гру, але так і не перенесли її на плюси :)

Чому варто знаходити баланс між принтами та С++?

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

Щодо оптимізації

У нас були великі проблеми з FPS, частина з них — щодо левелдизайну, Крім того, більше проблем мала сама логіка гри, великі масиви ігрових персонажів, які оновлювалися дуже часто, часті виклики до масивів, багато логіки на тікові івенти, велика кількість циклів у блупринтах. Тобто саме те, що ДУЖЕ не бажано використовувати у блупринтах. Таку логіку краще, і навіть ТРЕБА, переносити у код.

Через деякий час, коли гра тестувалась при максимальній кількості гравців, ми побачили, що реплікація почала з‘їдати багато ресурсів. Це було пов’язано з тим, що ми використовували дефолтні методи для реплікації, які вже реалізовані в анріалі, але не оптимізовували їх. Через це, коли ми відправляли дані про те, де знаходиться персонаж, в якій позиції його руки (контролери), одночасно з цим йшли дані про те, де знаходяться інші частини його тіла, хоча це вираховується у кожного клієнта локально. Це ми виявили лише за тиждень до презентації гри на Games Gathering.

Якби ми одразу писали цю частку логіки на С++, проблем вдалося б запобігти. Блупринти притупляють увагу до оптимізації. Зазвичай логіку на них пишуть швидко і не особливо думають, як воно працює. Головний девіз «працює — не чіпай». Проте, коли справа доходить до профайлінгу та оптимізації, доводиться все детально вивчати та оптимізувати.

Відео геймплею цієї гри:

Насправді ідеальний варіант — це комбінування коду та блупринтів.

На мій погляд, це такий варіант:

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

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

Загалом правила такі самі, як і для написання звичайного коду. Пишіть прості і зрозумілі речі. Наприклад:

У цьому випадку легко зрозуміти, що виконується. Після початку гри запуститься таймер — після якого заспавниться якийсь актор — і ми одразу ставимо йому статус друга для персонажа. Якщо логіка більш складна і хочеться поставити запитання «навіщо це»? — залишайте коментарі

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

Та в трохи більшому масштабі:


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


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

І тут нас зустрічає вся реалізація спауна актора.

Блупринти — дуже потужний інструмент. В ньому є наслідування, інтерфейси, структури тощо. З блупринтами можна працювати за всіма принципами ООП. Наприклад, створити базового персонажа, від нього створювати підкласи різних воїнів і тому подібне.

Базовий блупринт — клас персонажа:

Налаштований унаслідований від базового персонажа. І таких прикладів можна наводити безліч.

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

Візуально різні функції накладаються одна на одну, дроти тягнуться вздовж весь екран тощо. Подібні випадки:




Інколи це буває красиво:

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

Корисні поради

У підсумку, я можу дати такі поради:

  • Коли постає питання повноцінної розробки, то доцільно поєднувати блупринти та код. Якщо такої можливості немає, якщо необхідно створити нескладну логіку, або, наприклад, демо-версію, то блупринти можуть бути гарним варіантом.
  • Намагайтеся якнайменше використовувати важкі цикли, логіку у тіку (кожного кадру) і роботу з масивами даних у блупринтах. Це дуже «важкі» процеси для блупринтів, які садять FPS.
  • Краще частіше проводити профайлінг гри. Якщо хтось створить вибагливу і неоптимізовану логіку, що не буде помічено на початку, це в майбутньому призведе до проблем і витрат часу на перероблення коду.
  • Слідкуйте за чистотою свого коду, або вони перетворяться на спагетті.

Підписуйтеся на Telegram-канал @gamedev_dou, щоб не пропустити найважливіші статті і новини

👍ПодобаєтьсяСподобалось9
До обраногоВ обраному4
LinkedIn

Схожі статті



Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Підписатись на коментарі