Розробка скриптів для процедурної генерації елементів у VR іграх

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

Від імерсивних застосунків до ігрових світів і 3D-сцен

Наша виділена команда для VR/AR/MR-розробки, Unity-продакшну і 3D-моделювання та анімації — з власними кейсами і презентаціями.

Відвідати персоналізований сайт
Показано 1 з 1 послугУсі 242 послуг
Розробка скриптів для процедурної генерації елементів у VR іграх
Складна
~2-4 тижні
Часті питання

Наші компетенції

Які етапи розробки гри?

Останні роботи

  • image_games_mortal_motors_495_0.webp
    Розробка гри для компанії Mortal Motors
    685
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Покрокова стратегія у фентезі сеттингу With Fire And Sword
    866
  • image_games_second_team_604_0.webp
    Розробка ігри для компанії Second term
    492
  • image_games_phoenix_ii_606_0.webp
    3D-анімація – тизер для гри phoenix 2.
    534

Розробка скриптів для процедурної генерації елементів у VR іграх

Процедурна генерація у VR—це не просто випадкове розміщення об'єктів. Користувач знаходиться всередину сцени та фізично поворачує голову: артефакти стиковки тайлів, видимі паттерни повторюваності та «плаваючі» коллайдери ломять іммерсію моментально. Вимоги до якості процедурного контенту у VR на порядок вищі, ніж у плоских іграх.

Головні технічні складності процедурної генерації у VR

Перша та найболісніша проблема—генерація геометрії в главному потоці. Mesh.SetVertices() + Mesh.RecalculateNormals() на 50 000 вершин в OnEnable займає 12–18 мс на Snapdragon XR2, що дає прямий frame drop нижче 72 FPS—поріг комфортного VR. Розв'язується через Job System з IJobParallelFor та передачею даних через NativeArray<Vector3>, з подальшим застосуванням через Mesh.ApplyAndDisposeWritableMeshData() вже в главному потоці.

Друга проблема—коліізії для процедурної геометрії. MeshCollider з convex: false на динамічно генерованому меші на Quest заборонений PhysX з міркувань продуктивності (і Oculus VRC його не пропустить). Або розбиваємо геометрію на опуклі примітиви, або генеруємо спрощений collision mesh окремо через алгоритм Quickhull. У складних сценах—замінюємо MeshCollider на масив BoxCollider/SphereCollider за вузлами генерованої структури.

Третя—детерміністичність. Процедурна сцена повинна відтворюватися однаково при тому ж seed. Проблема виникає, коли генератор змішує Random.value (який залежить від глобального стану) та System.Random з фіксованим seed. Тримаємо весь генератор на одному екземплярі System.Random(seed) без звертання до UnityEngine.Random всередину pipline.

Як ми будуємо процедурні генератори для VR

Архітектура типового генератора для VR-рівня будується на трьох шарах: Layout Generator (розміщення ключових точок, шляхів, зон), Detail Populator (наповнення геометрією, мешами, ассетами з пула) та LOD Manager (керування детализацією залежно від дистанції до HMD).

Для генерації terrain-подібних структур використовуємо Perlin Noise через Mathf.PerlinNoise() з октавами—стандарт, але у VR діапазон висот критичний: перепади більше 30° нахилу поверхні викликають дискомфорт при ходьбі з фізичним контролером. Інтегруємо slope-check прямо в генератор, обрізаючи екстремальні значення.

Для міських та інтер'єрних сцен працює BSP (Binary Space Partitioning) або Wave Function Collapse—WFC особливо хороший для тайлових рівнів з чіткими правилами стиковки. Реалізуємо WFC з backtracking, обмеженим за depth, щоб не піти в нескінченний перебір при складних constraints.

З реального кейса: у проекті архітектурної VR-візуалізації генератор планування квартир на базі WFC спочатку давав 40% випадків з «невалідними» планами (кімната без виходу, перекривающиеся стіни). Виправили додаванням pre-pass валідатора з правилами зв'язності через BFS за графом кімнат—перед фінальною матеріалізацією меша.

Пул об'єктів критичний. Інстанцирування 500 GameObject через Instantiate() при змінові рівня—200–400 мс фриз. Використовуємо ObjectPool<T> з UnityEngine.Pool (доступний з Unity 2021), преднаповнений у фоновому потоці через AsyncInstantiateOperation.

Етапи роботи

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

Прототип генератора. Швидка реалізація з візуалізацією в Editor-режимі через Gizmos—клієнт видит результат без збірки під HMD.

Оптимізація під VR. Перенесення обчислень у Job System, реалізація пула, налаштування LOD для генерованої геометрії.

Інтеграція з рівнем. Підключення до NavMesh (baking після генерації через NavMeshSurface.BuildNavMesh()), налаштування Occlusion Culling для процедурних об'єктів.

Тестування. Стресс-тест: 100 генерацій з різними seed, перевірка на артефакти, валідація коліцій, замір часу генерації на цільовому HMD.

Тип генератора Строки розробки
Розстановка об'єктів за правилами (без геометрії) 3–7 днів
Тайловий рівень з WFC 2–3 тижні
Процедурна геометрія з Job System 3–5 тижнів
Повний генератор рівня з NavMesh та LOD 1–3 місяців

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