id: 241 slug: vr-game-level-event-logic-programming title_ua: "Програмування подієвої логіки рівнів у VR-іграх" tags: [vr-ar]
Програмування подієвої логіки рівнів у VR-іграх
Подієва логіка рівня у VR — це не скриптинг триггерів в OnTriggerEnter. Це управління порядком нарративу, станом середовища, реакціями NPC та навчальними підказками в тривимірному просторі, де гравець може дивитися в будь-яку сторону, стояти де угодно та взаємодіяти з об'єктами в довільному порядку. Лінійний скрипт ламається на третьому кроці: гравець підняв предмет раніше, ніж спрацював діалог, — і система не знає, у якому вона стані.
Де ламається проста подієва логіка у VR
Найпоширеніша проблема — серіалізація стану через булеві флаги. bool doorOpened, bool npcGreeted, bool puzzleSolved в GameManager. При 15 флагах починаються комбінаторні баги: флаг npcGreeted встановлена, але doorOpened ні, а користувач уже всередину — тому що пройшов крізь стіну при повторному заході. Відладити це без явної моделі станів майже неможливо.
Другий кейс — конкурентні події. Гравець бере ключ й одночасно наступає на триггер двері. Обидві події срабатують в одному кадрі, OnTriggerEnter та XRGrabInteractable.SelectEntered отрацовуть у невизначеному порядку. Якщо логіка не обробляє з врахуванням порядку — стан рассинхронізується.
Третя проблема специфічна для VR-тренажерів: пропуск обов'язкових кроків. Інструктор розробив обов'язковий порядок дій, але у VR користувач фізично може виконати крок 5 раніше кроку 2. Потрібна система, яка або м'яко блокує передчасні дії, або адаптує сценарій під фактичний порядок дій користувача.
Архітектура подієвої системи для VR-рівнів
Основа — конечний автомат сценарію (Level State Machine) з явними станами та переходами. Не флаги, а enum LevelState { Introduction, PuzzleActive, DoorUnlocked, Completed } з методами TryTransition(LevelState target).
Для складних нелінійних сценаріїв використовуємо ієрархічний State Machine або Behavior Tree:
-
BehaviorDesignerабо кастомний BT для NPC-реакцій - Для загальної логіки рівня — власний
LevelOrchestratorна основіIEnumerator-корутин абоUniTask
Event Bus — центральний брокер подій. Усі компоненти рівня публікують події в шину, не знаючи один про одного: EventBus.Publish(new KeyPickedUpEvent(keyId)). LevelOrchestrator підписана на потрібні події та оновлює State Machine. Це розриває прямі залежності між Trigger-компонентами та Orchestrator-ом.
Реалізуємо через event Action<T> або ScriptableObject-based EventChannel (паттерн з Unite Austin 2017): [CreateAssetMenu] KeyPickedUpEventChannel : EventChannelBase<KeyPickedUpEvent>. Кожен EventChannel — окремий ассет, ссилки між компонентами через інспектор — не через Find().
Checkpoint система — для тренажерів критично: кожен завершений крок серіалізується в SessionData. При повторному прохождении або продовженні після паузи — стан восстановляется точно. Зберігаємо не флаги, а снимок стану State Machine + список завершених подій з timestamps.
Специфіка VR-нарративу
У VR гравець дивиться куди хоче, тому класичне «нарративне подія в центрі екрана» не працює. Потрібні механізми м'якого спрямування погляду:
Spatial Audio Cue: звук видається з точки інтересу — гравець поворачивается природно. Реалізується через AudioSource з 3D spatial blend + ReverbZone.
Peripheral Attention Trigger: яскравий ефект (частинки, світло) в периферійному полі зору — працює ефективніше, ніж стрілка-указатель UI.
NPC Look At: NPC дивиться на гравця та починає діалог лише коли гравець дивиться на нього (кут < 45°). Перевіряється через Vector3.Dot(playerHeadForward, directionToNPC). Це запобігає ситуації, коли діалог починається «в спину».
З конкретного кейса: у VR-тренажері з пожарної безпеки гравець повинен виконати 7 кроків евакуації строго за порядком. Спочатку логіка була на флагах — при тестуванні 40% користувачів знаходили спосіб «сломати» сценарій. Після переписування на явний State Machine з TryTransition() — валідація порядку стала частиною архітектури, а не набором if-перевірок. Completion rate без помилок виріс з 55% до 89%.
Відладка та інструменти
Кастомний Level State Viewer — Editor Window, що показує поточний стан State Machine у реальному часі в режимі Play. Список активних подій, історія переходів, pending events у черзі. Без цього інструмента відладка подієвої логіки — Debug.Log() в темноті.
Event Log: усі évény записуються з timestamp та stack trace у кільцевий буфер. При баґу — миттєва відповідь на питання «що сталося до цього».
Етапи роботи
Аналіз сценарію. Розбираємо логіку рівня, виявляємо стани, события, залежності між ними.
Проектування State Machine. Діаграма станів та переходів перед кодом.
Розробка. EventBus, Orchestrator, інтеграція з VR-компонентами (XR Interaction Toolkit events).
Відладочні інструменти. Level State Viewer, Event Log.
Тестування. Усі граничні випадки: паралельні события, пропуск кроків, повторне прохождение.
| Масштаб рівня | Орієнтовні строки |
|---|---|
| Лінійний сценарій, 5–10 подій | 1–2 тижні |
| Нелінійний рівень, 20–40 подій | 3–5 тижнів |
| Складний тренажер з BT та checkpoint системою | 2–4 місяці |
Вартість розраховується після розбору сценарію та оцінки складності логіки переходів.





