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

Зворотні виклики геймплея

Хоча вибракування оклюзії значно зменшує кількість об'єктів, які потрібно рендерити, є й інші витрати на підтримку об'єктів у грі, крім остаточного рендеринга. Наприклад, у Godot анімовані об'єкти все ще будуть анімуватися незалежно від того, з'являються вони на екрані, чи ні. Це може зайняти багато обчислювальної потужності, особливо для об'єктів, які використовують програмне забезпечення для покриття (наприклад шкіри) (і це покриття розраховується на процесорі).

Не бійтеся, кімнати і портали можуть вирішити ці проблеми, і багато іншого.

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

Ігрова зона не обмежується лише об'єктами, які ви можете побачити перед собою. Монстри з ШІ позаду вас все ще повинні атакувати вас, коли ви повернуті до них спиною! У Godot ігрова зона визначається як потенційно видимий набір (potentially visible set (PVS)) кімнат, з кімнати, в якій ви зараз перебуваєте. Тобто, якщо є якась частина кімнати, яку можна подивитися з будь-якої частини кімнати, в якій ви перебуваєте (навіть з кута), вона розглядається в межах PVS, а значить і ігрової зони.

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

Як монстр знає, чи знаходиться він в ігровій зоні?

Ця проблема вирішується тому, що система порталів містить підсистему під назвою Монітор гри (Gameplay Monitor), яку можна вмикати і вимикати з RoomManager (Керівника кімнат). Коли ввімкнено, будь-які переміщувані об'єкти, які переміщуються всередину, або назовні, ігрової зони (будь то їх переміщення, або переміщення камери), відтворюватимуть зворотні виклики, щоб повідомити про цю зміну.

Ви можете отримати ці зворотні виклики як сигнали signals, або як сповіщення notifications.

Сповіщення можна обробляти на GDScript, або інших скриптових мовах:

func _notification(what):
        match what:
                NOTIFICATION_ENTER_GAMEPLAY:
                        print("notification enter gameplay")
                NOTIFICATION_EXIT_GAMEPLAY:
                        print("notification exit gameplay")

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

Насправді, ви не просто отримуєте ці зворотні виклики для об'єктів ROAMING. Крім того, кімнати та групи кімнат також можуть отримувати зворотні виклики. Наприклад, ви можете використовувати це, щоб викликати певну поведінку ШІ, коли гравець досягає певних точок на рівні.

Вузли VisbilityNotifier та VisibilityEnabler

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

Можна оптимізувати цю проблему за допомогою вузла VisibilityNotifier (Сповіщення про видимість), або його, трохи простішої у використанні, версії - вузла VisibilityEnabler (Увімкнена видимість). VisibilityEnabler можна використовувати для вимкнення анімації та присипляння фізики, коли об'єкт знаходиться за межами поля зору. Для цього ви просто поміщаєте вузол VisibilityEnabler у вашу під-сцену (наприклад, в монстра). Решту зробить вузол. Щоб отримати повну інформацію, зверніться до документації вузла :ref:` VisibilityEnabler<class_VisibilityEnabler>`.

../../../_images/visibility_enabler.png

Чи може VisibilityEnabler вимкнути об'єкти вибракувані оклюзією? Насправді може. Все, що вам потрібно зробити, це включити Монітор гри в RoomManager (Керівнику Кімнат), а решта відбудеться само.

Вузол RoomGroup

RoomGroup (Група Кімнат) - це спеціальний вузол, який дозволяє мати справу відразу з групою кімнат, замість того, щоб писати код для кожної індивідуально. Це особливо корисно в поєднанні з ігровими зворотними викликами. Найважливішу роль вузли RoomGroup відіграють у розмежуванні "внутрішніх" та "зовнішніх" областей.

../../../_images/roomgroups.png

Наприклад, коли ви знаходитесь на вулиці, ви можете використовувати для освітлення Спрямоване Світло. Коли зовнішній вузол RoomGroup отримає зворотний виклик enter gameplay, ви можете ввімкнути світло, і можете вимкнути його, коли RoomGroup вийде з ігрового процесу. З вимкненим світлом продуктивність буде збільшуватися, оскільки немає необхідності використовувати його у приміщенні.

Це простий приклад використання RoomGroup для ввімкнення та вимкнення Спрямованого Світла. Зверніть увагу, що ви також можете використовувати сигнали для зворотних викликів (вибір залежить від вас):

../../../_images/roomgroup_notification.png

Порада

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

Внутрішні кімнати

Існує ще один трюк з використанням вузлів RoomGroup. Дуже поширене бажання - мати ігровий рівень зі змішаним відкритим і закритим середовищем. Ми вже згадували, що кімнати можуть бути використані для представлення як кімнат в будівлі, так і районів ландшафту, таких як каньйон.

Що станеться, якщо ви забажаєте мати будинок в 'кімнаті' місцевості?

З функціональністю, описаною до цих пір, ви можете це зробити - вам потрібно буде зовні навколо будинку розмістити портали, утворюючи непотрібні кімнати над будинком. Так було зроблено в багатьох іграх. Але що якщо був простіший спосіб?

Виявляється, простіший спосіб є. Godot підтримує кімнати "всередині" кімнат (ми будемо називати їх "внутрішні кімнати"). Тобто ви можете розмістити будинок в кімнаті місцевості, або навіть будівлю, або набір будівель, і навіть мати вихідні портали в різних кімнатах місцевості!

Щоб створити внутрішні кімнати, вам не потрібно розміщувати кімнату в іншій кімнаті в дереві сцени - насправді ви отримаєте попередження, якщо спробуєте це зробити. Натомість створіть їх як звичайні кімнати. Внутрішні кімнати мають бути згруповані разом у вузлі RoomGroup. В інспекторі RoomGroup має параметр Room Group Priority (Пріоритет групи кімнат), який за замовчуванням дорівнює 0.

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

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

Деякі відмінності:

  • Портали між внутрішніми кімнатами і зовнішніми кімнатами завжди повинні розташовуватися у внутрішній кімнаті.

  • Портали внутрішніх кімнат не розглядаються як частина зв'язок зовнішніх кімнат.

  • STATIC та DYNAMIC розлогі об'єкти з зовнішніх кімнат не будуть проникати у внутрішні кімнати. Якщо ви хочете, щоб об'єкти перетинали ці портали, помістіть їх у внутрішню кімнату. Це робиться для запобігання проникненню в будівлі великих об'єктів, таких як ділянки місцевості.

Зразок внутрішньої кімнати:

Намет - це проста кімната всередині кімнати місцевості (яка містить землю, дерева і т. д.).

../../../_images/tent.png

Примітка

Щоб використовувати внутрішні кімнати для будівель, зазвичай непогано відокремити внутрішній меш будівлі від зовнішнього. Зовнішній меш можна розмістити в зовнішній кімнаті (так його можна побачити ззовні, але не зсередини), а внутрішній повинен розташовуватися у внутрішній кімнаті (так його видно тільки всередині, або через портал).

../../../_images/tent_terrain.png

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

Сцена з "Діорама Еко сцена" від Одо, з невеликими змінами для ілюстрації цілей. CC Attribution

Сцени внутрішніх кімнат

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

../../../_images/house_scene.png

Ми створили вузол Кімнати (який стане внутрішньою кімнатою), в який помістили меші інтер'єру. Ми також створили Портал без посилань (тому буде використовуватися автоматичне посилання). Зовнішній меш екстер'єру не знаходиться в кімнаті. Він буде автоматично розміщений, і ми сподіваємося, що він буде розміщений у зовнішній кімнаті.

Однак є проблема. Наївний алгоритм автоматичного розміщення буде дивитися на центр меша екстер'єру, і намагатися розмістити його всередині внутрішньої кімнати. Ми хочемо уникнути цього якимось чином, оскільки ідея зовнішнього меша полягає в тому, щоб знаходився назовні, тому, щоб все працювало, він повинен бути у зовнішній кімнаті.

Для обходу цієї проблеми, існує спеціальна настройка, яка дозволяє виставити перевагу автоматичного розміщення у зовнішній кімнаті. Кожен об'єкт має параметр Autoplace Priority (Пріоритет авто-розміщення). При значенні 0, немає переваги (об'єкт буде розміщений в кімнаті з найвищим пріоритетом).

Однак, якщо ми встановили цей пріоритет, наприклад на -1, автоматичне розміщення завжди вибиратиме пріоритетну кімнату -1 (якщо вона присутня в цій локації). Отже, якщо ми поставимо пріоритет зовнішньої кімнати -1, він завжди поміщатиме наш екстер'єр у нашу "зовнішню" кімнату.

../../../_images/autoplace_priority.png

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

Примітка

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

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

../../../_images/island.png

Екстер'єри будинку будуть розміщені в зовнішньому приміщенні, а тому їх завжди можна побачити при погляді ззовні. Інтер'єри відображатимуться лише тоді, коли буде видно портали входу.