Прототип, выросший из теста персонажа с костными анимациями, мыслей о различном использовании текста в окружении/механиках, неких инопланетных мотивов и программирования ботов, использующих скрипты паучьего передвижения.
В процессе я добавил сюда элементы концепции восхождения по этажам внеземной пирамиды, ранее упомянутой в списке задумок для диаблоидов. Также здесь реализована идея связанных измерений, с которой я в принципе люблю экспериментировать в различных своих проектах.
После нескольких итераций, вот что получилось:
Игра-эксперимент
В начале демо герой попадает на ландшафт с респавнящимися паукообразными врагами. В стандартном измерении можно стрелять (левая кнопка мыши) или (зажав правую кнопку мыши) двигаться ускорено, оставляя за собой геошлейф. Также здесь можно найти капсулы-сундуки, открывающиеся при нажатии E и дающие какой-либо "предмет". Каждая "вещь" может выпасть случайной степени редкости (белая, синяя, зелёная, фиолетовая, оранжевая).
В качестве индикаторов "здоровья" персонажа используются слова (body/mind/hope). Когда один из индикаторов уничтожен, то героя выбрасывает на другую сторону (связанное измерение), где он оказывается заперт на какое-то время, пока показатели не восстановятся.
![стандартное измерение стандартное измерение](https://habrastorage.org/getpro/habr/upload_files/579/e92/89f/579e9289fea1924abf72b0677ef08c05.jpg)
![другая сторона другая сторона](https://habrastorage.org/getpro/habr/upload_files/40c/d30/ac6/40cd30ac6c674a830fbd4c8f7220369e.jpg)
Враги гибнут от нескольких попаданий (маневрируя можно заставить их стрелять по своим). При этом, на той стороне от них остаются фрагменты кода и специальные сферы, подбирая которые можно собирать буквы имени. Собрав все буквы имени на первом уровне герой получает меч-ключ (применяется на левую кнопку мыши), открывающий проход к порталу на следующий уровень.
"Инвентарь" реализован, как дополнительное, карманное, измерение, куда можно перейти по нажатию Enter. Здесь можно увидеть полупрозрачную версию персонажа и звёздочки, отмечающие слоты "предметов" (или "достижений") - сюда попадают полученные из капсул "вещи".
На втором и третьем уровнях обитает уже другой вид врагов - рыбообразные. После уничтожения некоторых из них, на той стороне остаются сферы, дающие возможность бросать светильники (правая кнопка мыши), которые цепляются за поверхности.
Демоверсия
Видеонарезка с моментами геймплея из последней версии 01_05
Скачать демо для Windows 64-bit можно на страничке itch.io (около 230Мб в архиве): https://thenonsense.itch.io/anotherwords
Управление:
WAD - перемещение
S - переключить измерение (на той стороне отключаются возможности стрельбы и быстрого перемещения, кроме того нельзя возвращаться обратно пока не истечёт TIME либо не будет разрушена SEAL, после чего связь восстановится)
E - открыть сундук
Enter - открыть/закрыть измерение "инвентаря"
мышь - управление камерой (колесо регулирует зум)
Левая кнопка мыши - выстрел (или применение вербального оружия на той стороне)
Правая кнопка мыши - быстрое перемещение (или бросок светильника на той стороне)
L - перезапустить мир
P - выход из приложения
О том, как что устроено
В Unigine engine предусмотрен встроенный инструментарий для относительно простого вывода плоскости с текстом в трёхмерное пространство - ObjectText. По сути узел-пустышка со специфическими текстовыми свойствами, доступ к которым из кода можно получить, представив полученную ссылку на узел as ObjectText (либо сразу получая ссылку в формате ObjectText'а, а не узла, если манипуляции со свойствами самого узла не понадобятся).
Далее, если хочется скрыть текст, то можно просто прописать "пустую" строку вместо отключения самого узла. Только конкретно в Unigine конструкция "" порождает визуальный баг, чтобы этого не было нужно внутри кавычек поставить пробел - " ". Цвет текстового компонента задаётся через 4-вектор, где параметры RGBA выставляются значениями от 0 до 1 (хотя в самом редакторе цвет в этом формате не представлен, показывая вместо этого шестнадцатеричную запись, а также настройки цвета с диапазонами от 0 до 255).
Так как в проекте используется "переключение реальностей", то для этого были сделаны некоторые слои с объектами, включаемые и отключаемые при надобности. Для того, чтобы некоторые вещи спавнились исключительно в нужном слое очень пригодился метод Clone(), так как клоны сразу создаются в той же ветке иерархии сцены, что и клонируемый объект. Более обычный метод - LoadNode() создаёт заранее сохранённый "префаб" сразу в сам мир. В принципе, почти в каждом игровом движке оба эти подхода присутствуют.
Что касается улучшения производительности для статических мешей - в Unigine предусмотрен такой способ оптимизации однотипной геометрии, как кластеры. Своеобразная папка с кучей инстансов одного и того же объекта, которые могут иметь разный наклон и скейл. Правда прицельно расставлять отдельные элементы средствами редактора - не совсем удобно, потому как если для точной привязки к координатам достаточно включить примагничивание и поставить мировые координаты вместо локальных, то при вращении элементов очень часто сбиваются углы на какие-то сотые и тысячные доли (то есть поворачиваешь элемент ровно на 90 градусов, а он время от времени сбивается на что-то вроде 89.999). Опять же, нет возможности выделить пачку объектов и ввести прибавку по нужной координате +N. Нужно именно вписывать конкретное число, что очень замедляет процесс, так как таким способом можно сдвинуть один объект или линию, но не больше.
![третий уровень, собранный в Blender третий уровень, собранный в Blender](https://habrastorage.org/getpro/habr/upload_files/ea3/b3b/cd6/ea3b3bcd6a8b655d22397728aecb1783.jpg)
![9 уникальных элементов, из копий которых собран уровень 9 уникальных элементов, из копий которых собран уровень](https://habrastorage.org/getpro/habr/upload_files/845/d50/f2f/845d50f2f4762f5200dfbb2a417a74c6.jpg)
Поэтому для сборки уровня под кластеры я пользовался Blender'ом, в котором можно куда удобнее и быстрее расставлять элементы. Таким образом, например, второй уровень собран из 3 расклонированных элементов, а третий из 9. Коллайдеры тоже можно было моделить сразу в Блендере, но тут уже разница была не так принципиальна, поэтому расставлял их уже внутри движка.
![расстановка коллайдеров (слева), сборка враждебной "рыбы" (справа) расстановка коллайдеров (слева), сборка враждебной "рыбы" (справа)](https://habrastorage.org/getpro/habr/upload_files/248/f77/092/248f77092cf76143ed07c7350d15ce29.jpg)
Больше картинок
![закрытая капсула с "предметом" закрытая капсула с "предметом"](https://habrastorage.org/getpro/habr/upload_files/e7b/6b3/964/e7b6b39640d9d0b209ea290981d76c78.jpg)
![персонаж собрал меч-ключ на той стороне персонаж собрал меч-ключ на той стороне](https://habrastorage.org/getpro/habr/upload_files/c92/f18/647/c92f18647415c370578b1cc9175df001.jpg)
![эффект размытия при переходе между измерениями эффект размытия при переходе между измерениями](https://habrastorage.org/getpro/habr/upload_files/3cb/4c7/587/3cb4c7587a39398cb1830c2cabe6c4a2.jpg)
![третий уровень третий уровень](https://habrastorage.org/getpro/habr/upload_files/b58/5cb/ff5/b585cbff56d9e46353b1ec3421cec0f7.jpg)
![карманное измерение "инвентаря" карманное измерение "инвентаря"](https://habrastorage.org/getpro/habr/upload_files/0ff/967/b07/0ff967b07658d499ec123f3764681d17.jpg)
![чтобы снять печать нужно выбивать буквы у "потусторонних рыбок" чтобы снять печать нужно выбивать буквы у "потусторонних рыбок"](https://habrastorage.org/getpro/habr/upload_files/6ff/e07/e3b/6ffe07e3bd366e44eacc16b2f1493932.jpg)
![второй уровень второй уровень](https://habrastorage.org/getpro/habr/upload_files/d61/4e2/b80/d614e2b8065c24defa4652dcf15aef9b.jpg)