Архитектура движка
Существуют разные подходы к настройке игровой архитектуры, от комплексных решений, в которых игровая логика объединена с движком, до кучи отдельных модулей, каждый из которых отвечает за одну часть функциональности. UNIGINE находится где-то посередине этой шкалы, он включает в себя все, что нужно для реализации игры или другого 3D-приложения, за исключением логики приложения, сетей и ИИ. UNIGINE включает в себя только типичную игровую логику, общую для приложений всех типов, и это сделано намеренно.
Это может показаться не преимуществом, потому что для создания игры нужно много программировать и самостоятельно реализовывать общие функции, широко используемые в играх требуемого жанра. Тем не менее, отсутствие логики игры, ориентированной на определенный жанр, не так уж плохо, поскольку делает UNIGINE универсальной библиотекой, которую легко использовать в различных проектах. Более того, разработчики не привязаны к какому-то конкретному жанру, они могут экспериментировать сразу с несколькими жанрами, что крайне сложно, если используется специализированный движок. Например, сложно совместить шутер и гоночную игру на движке, созданном исключительно для шутеров от первого лица. Кроме того, UNIGINE позволяет подключать внешние модули, которые могут содержать специфичные для жанра функциональные возможности, а также могут использоваться повторно. Все это делает UNIGINE довольно гибкой базой для широкого спектра 3D-приложений.
Понять архитектуру UNIGINE очень важно как для разработчиков, так и для создателей контента. Первые будут знать, что им разрешено делать, чего они могут достичь и чего ожидать от UNIGINE. Последние поймут, как будет обрабатываться их контент. Вот почему эта статья представляет собой краткий общий обзор рабочего процесса UNIGINE.
Приведенная ниже диаграмма демонстрирует взаимосвязи между внутренними компонентами UNIGINE и различными внешними объектами.
Все начинается, когда пользовательское приложение вызывает функции C++ API UNIGINE. Эти вызовы выполняются с использованием C++/C#. C++ приложение напрямую вызывает функции API. Приложение C# использует C# Wrapper (UnigineSharp.dll), которое, в свою очередь, использует C Wrapper (UnigineWrapper.dll, UnigineWrapper.so) для взаимодействия с UNIGINE API.
Логика приложения может быть реализована непосредственно в классах AppWorldLogic, AppSystemLogic и AppEditorLogic или через набор Компонентов с использованием Компонентной системы, включенной в API.
Функциональность приложения может быть расширена с помощью плагинов движка. UNIGINE предоставляет набор готовых к использованию плагинов, однако вы можете реализовать пользовательский. Вы также можете реализовать пользовательские плагины редактора , которые расширяют функциональность редактора UNIGINE.
Вызовы API передаются Движку, который инициализирует необходимые ресурсы: регистрирует расширения, загружает основные данные, файлы конфигурации, файлы пользовательского интерфейса, каталоги плагинов. Поскольку все эти ресурсы организованы в специальном каталоге данных и, более того, могут быть упакованы, они загружаются с помощью Файловой системы. Кроме того, файловая система отслеживает порядковый номер файлов. Обратите внимание, что если вы добавляете файлы в этот каталог после завершения инициализации, вам необходимо перезагрузить компонент файловой системы.
После инициализации Движок запускает другие подсистемы. Приведенная выше схема содержит основные из них:
- App управляет основным циклом и управляет графическим контекстом (управляет событиями элементов управления, обновляет параметры окна).
- Render рендерит сцену. Для выполнения своих задач ему нужны дополнительные ресурсы: текстуры, сетки и анимация. Необходимые графические ресурсы передаются для рендеринга из файловой системы .
- World загружает файлы, необходимые для построения текущей сцены, и определяет набор видимых нод, которые позже будут отправлены на Рендеринг. Мир также сообщает Sound, когда и как воспроизводить звуки окружающей среды, какие источники расположены где-то в мире и обладают пространственными свойствами. Мир работает вместе с Physics, который выполняет физические вычисления (обнаружение столкновений, решение стыков, плавучесть жидкости и так далее). Короче говоря, Мир не рисует объекты, не воспроизводит звуки и не выполняет физические вычисления сам по себе. Вместо этого он делегирует эти задачи соответствующим подсистемам.
- Game передает Миру (по запросу) время в секундах, которое потребовалось для завершения последнего кадра. Мир обновляется в соответствии с полученным значением.
- Physics управляет симуляцией физики в Мире.
- Input (элементы управления) обрабатывает ввод от устройств ввода и передает обратную связь. Приложение может прочитать и каким-то образом обработать полученные входные данные, если требуется.
- Materials и Properties управляет материалами и свойствами. Они загружаются из файловой системы .
- Sound получает звуки из файловой системы и передает их на звуковую карту для воспроизведения.
- GUI рисует пользовательский интерфейс. В UNIGINE объекты GUI могут быть как автономными, так и частью отображаемого виртуального мира. В последнем случае они управляются миром так же, как и другие ноды. Когда отображается визуализированное изображение, возможно, содержащее графический интерфейс, пользователь начинает взаимодействовать с миром. Пользователь может влиять на мир с помощью различных устройств ввода. Входные данные с этих устройств отправляются в графический интерфейс пользователя и в Controls. Графический интерфейс обрабатывает входные данные, обнаруживает выбранный элемент и выполняет соответствующую функцию обратного вызова. Подсистема Controls обрабатывает входные данные, которые не связаны с графическим интерфейсом, например действия игрока в игре. Обратите внимание, что графический интерфейс всегда получает входные данные перед элементами управления и, следовательно, имеет более высокий приоритет.