Какой фреймворк использует unity

Обновлено: 03.07.2024

На обложке демо-игра Megacity. Она содержит 4,5 млн элементов Mesh Renderer, 5000 динамических транспортных средств, 200 000 уникальных строительных объектов и 100 000 уникальных аудиоисточников. Но самое удивительное, что вся эта мощь запустилась на Iphone X при 60 кадрах в секунду . Как все это возможно?

Пару лет назад компания Unity представила свой стек DOTS, на котором и построен проект Megacity. Это некий список технологий, которые в совокупности позволяют колдовать и ускорять ваш проект в десятки раз. В корне всей магии лежат 2 простых заклинания:

Если правильно управлять данными, процессору будет легче их обрабатывать, а если их легче будет обрабатывать, то игрокам будет легче жить.

Количество ядер процессора растет, но код среднестатистического программиста не использует все ядра процессора. А значит игрокам все же живется туго. Фреймрейт ведет себя как Джокер - непредсказуемо.

Для того, чтобы Unity программистам удалось осуществить вышеописанные постулаты, компания выпустила дополнительные пакеты:

Job System - Пишите многопоточный код, даже если вы не знаете что такое "Race condition" или "Context switch".

Burst Compiler - Ускорьте код в 10 раз, просто добавив атрибут и отказавшись от ссылочных типов.

Unity Mathematics - Специальная математика, адаптированная под компилятор Burst.

Native Container - Обертка над неуправляемой памятью. Это такие же List, Array, Queue, но живут в мире без мусора. Мусор - это ваш код. Мусор - это то, что могут оставлять после себя мертвые ссылочные типы. Сборкой мусора в проекте занимается некий дворник - Garbage Collector, но он очень медленный и злой дядька . Да и Greenpeace советует убирать после себя трупы, не правда ли?

А сердцемDOTS является:

Entities - архитектурный паттерн Entity Component System (ECS), который ставит во главу угла данные, а не объекты, и тем самым переворачивает привычное представление о программировании среди ценителей ООП . Подобный подход развивает идею композиции над наследованием и позволяет легко адаптироваться под динамичные потребности гейм-дизайнера.

ECS стоит рассматривать в первую очередь как архитектурное решение. Скорость - это бонус.

На текущий момент DOTS выглядит скорее проклятьем Unity Technologies , чем волшебной палочкой. Стек до сих пор не вышел в официальный релиз. И неизвестно когда DOTS выйдет в официальный релиз. Сейчас это крайне нестабильная штука, которую точно не стоит использовать в Production проекте.

Поэтому, давайте попробуем применить подход Entity Component System (ECS) в своем проекте.

Производительность! Бесплатно и без регистрации

Entity Component System - это сердце нового подхода от Unity. Но одновременно и самая нестабильная часть всего стека DOTS . Что же это такое?

Entity - это все, что вас окружает. Ваша кошка, сын маминой подруги, пицца - это все entity.

Component - это то, что делает ваш Entity особенным. У кошки есть хвост, у сына маминой подруги - мозги, у пиццы - кетчуп. Это все - компоненты.

System - логика, которая управляет всеми entity, у которых есть тот или иной набор компонентов. Хвост помогает всем кошкам балансировать в пространстве, мозги помогают всем сыновьям маминой подруги быть круче вас, а кетчуп позволяет любой пицце быть вкусной.

Если перенести аналогию на игровые объекты, то ваш персонаж в игре - это Entity. Компонент физики - Rigidbody, а система - это то, что будет управлять всей физикой на сцене, включая вашего персонажа в игре.

Рецепт ECS под соусом Leo

Поиск Гугл по рецептам приводит нас к самому вкусному результату:

Leo ECS - очень легкий и быстрый ECS фреймворк, который не требует какого-то специфичного игрового движка. Он прост, быстр и не форсирует вашу интеграцию с Unity Engine.

Помимо этого, на данный момент Leo ECS самый популярный ECS фреймворк после Entitas

Entitas - аппетитный фреймворк с самым большим комьюнити, но вся его проблема в том, что он работает на классах. Добавлять этот ингредиент сейчас не модно, повара предпочитают использовать структуры на компонентах. Классы почти в 2 раза медленней структур в синтетических тестах, т.к хранят в памяти ссылку. А данные тесты демонстрируют отставание по скорости готовки от 10 до 20 раз.

Другие ECS рецепты, которые могут вас заинтересовать

ECS.ME - потрясающий ECS фреймворк для Unity, приготовленный для сетевых игр с элементом отката (RollBack). Эдакий некоммерческий аналог Quantum от Exit Games. Рецепт очень-очень крутой и вкусный. Но чтобы rollback не дал трещину, нужно четко следовать правилам данного фреймворка.

EgoECS - ECS фреймворк с сильнейшей интеграцией в Unity. С его помощью можно готовить MonoBehavior в качестве компонентов. Если вам не важна скорость работы, EgoECS выглядит весьма хорошим рецептом. Каждая система - это всего 1 фильтр, кому-то такой подход может скручивать руки при написании кода.

Svelto ECS - очень амбициозный рецепт, с очень сложным API. Но я должен был его упомянуть. Скорее всего он не подходит новичкам, но если вы заинтересовались, то на habr существует перевод Wiki данного фреймворка.

Actors - изначально разрабатывался как набор утилит. В рецепте присутствует шина событий(глобальный ивенты), которая может нарушить порядок вызовов функций и никак не относится к ECS. Реактивщина в ECS может сбить вас с толку при поиске багов / ошибок в вашей игре.

ОБНОВЛЕНО! Насколько увеличится скорость?

Я провел классический эксперимент, создал 100 000 GameObject и двигал их по вектору Z на 0.1 значение.

Что вы узнаете на этой странице: советы по использованию Unity Test Framework (UTF) для контроля качества ваших проектов. UTF — это один из важнейших инструментов для контроля качества; это система автоматизированного тестирования как в Editor, так и на поддерживаемых платформах. И эта система доступна всем пользователям Unity!

Новый API Test Runner расширяет гибкость и возможности UTF, обеспечивая максимальный охват тестирования. Эта система доступна в Unity Package Manager, благодаря чему мы можем быстрее устранять ошибки и обновлять ее. Кроме того, это означает для вас локальную доступность исходного кода UTF. Изучайте исходный код, улучшайте его при отладке и меняйте на свое усмотрение.

Подробнее об этой системе можно узнать из доклада об UTF на Unite Copenhagen, который представили разработчики инструментария и тестов Ричард Файн и Кристиан Варнеки.

Тестируйте игровой код с помощью Unity Test Framework

If you are new to the Unity Test Framework (UTF), read the documentation for an introduction. In brief, the UTF enables Unity users to test their code in both Edit Mode and Play Mode, and also on target platforms such as Standalone, Android, iOS, and others.

You might also find these blog posts informative:

Another related solution to learn about is Backtrace, an error management platform that enables you to capture crashes and exceptions and fix them quickly. Watch this Unite Now session for an in-depth introduction.

Тесты можно запускать автоматически, любым скриптом, с помощью Test Runner API (см. API ниже). Интерфейс позволяет получать список тестов, которые запускаются в режиме редактирования, в режиме игры или в обоих режимах без необходимости их запуска. Вы можете подключить обратные вызовы регистрации и дерегистрации в начало и конец каждого теста на каждом уровне в рамках цикла тестирования, то есть для каждой тестовой сборки, для каждого тестового устройства, для каждого тестового класса и отдельного теста.

В начале вы получите информацию о ходе запускаемого теста. После завершения теста вы увидите его результаты.

Помимо запуска UTF в режиме игры в редакторе Unity, новая точка настройки позволяет запускать тест на целевых устройствах. Она вызывается до сборки Player и позволяет изменить настройки сборки Player. Например, изменить настройки запуска тестов и указать расположения сборок.

Разделение процессов сборки и запуска удобно при необходимости провести тестирование на целевом устройстве, не подключенном к локальной машине, например, если оно находится в облаке (или при наличии нескольких устройств в облаке).

Для этого сначала нужно изменить сам процесс сборки тестового приложения Player. Сделать это можно так:

  • отключите параметр AutoRun, чтобы после завершения не происходило запуска Player и запланированных тестов;
  • сохраните сборку в известное расположение, а не во временную папку системы (куда она сохраняется по умолчанию);

добавьте свои настройки отчета по результатам на стороне Player (с помощью интерфейса обратных вызовов) для записи всех результатов в XML или в файл любого удобного вам формата.

Ниже приведены примеры кода для разделения процессов сборки и запуска. В докладе на конференции Unite (отметка 6:28) Ричард Файн подробно раскрывает оба аспекта этого приложения — и процесс сборки, и составление отчета по результатам.

Разделение сборки и запуска: сохранение результатов и запуск

Пример кода можно увидеть ниже. Ричард объясняет код для этого приложения в докладе на Unite (отметка 11:50).

Выполнение тестов до сборки может быть сопряжено с некоторыми сложностями, поскольку процессу сборки нужно, чтобы тесты запускались обратным вызовом, чтобы не было возможности выполнить цикл update для движка. Но такой подход полезен возможностью проверить базовую функциональность, не тратя время на процесс сборки (который может занимать несколько минут для некоторых проектов).

Вы можете реализовать это с помощью интерфейса IPreprocessBuildWithReport, аналогично реализации любых других операций, выполняемых до сборки. Как и в других случаях, для получения результатов нужно зарегистрировать обратный вызов.

В режим игры невозможно переключиться в процессе сборки, но можно использовать Test Runner API для выполнения тестов в режиме редактирования. Эти тесты можно выбрать с помощью фильтра по категориям, например, категория «валидационный тест перед сборкой». Эти тесты можно выполнять синхронно.

Это приложение можно разбить на две части: ResultCollector и препроцессор, о котором Ричард рассказывает в своем докладе (отметка 15:20).

Смотрите демонстрацию работы Test Runner API от Кристиана и Ричарда. Смотрите весь доклад, если хотите узнать ответы на заданные им вопросы!

P.S. Если вы сведущи в данном вопросе и считаете по-другому, то я не против, если вы меня таки переубедите в необходимости MVC при разработке игры на Unity, но постарайтесь, пожалуйста, объяснить свою точку зрения. :)

P.P.S. Это мой первый вопрос тут. До этого частенько тут бывал, находил интересующие вопросы и ответы на них. Теперь вот решил сам задать. =) Надеюсь, примите добролюбиво. :p


12.1k 12 12 золотых знаков 37 37 серебряных знаков 68 68 бронзовых знаков Ну, классической альтернативой MVC является MVP/MVVM (применяется в WPF). @VladD Не слыхал про MVP. Теперь хоть вижу, в каком направлении рыть, спасибо. Примерчика (в случае с Unity) не подкинете?) Я был бы просто счастлив. :) @JerryGreen: Нет, не смогу, я не большой спец в Unity. По WPF есть много примеров на сайте, наверняка легко гуглятся.

Из опыта изучения различных стартер китов могу предположить, что на данный момент разработчики, использующие Unity, вообще очень редко используют какие-либо общепринятые шаблоны программирования. Для себя я вижу причину этому в небольшом времени жизни игры как продукта, плюс специфика самого Unity. Раз, два - и в производство, так сказать.

Если говорить о способе организации пользовательского интерфейса, для себя я решил, что оптимальная модель работы будет нечто аналогичное MVVM, плюс шаблон Команда.

В сцене создаем пользовательский интерфейс, затем объект-менеджер, который будет отвечать за интеграцию интерфейса с логикой. Назовем его, например, GUIImpl . Класс должен быть наследником MonoBehaviour для того, чтобы мы могли работать с ним в редакторе. В приведенном ниже примере я использую NGUI для самого интерфейса.

Следующим шагом необходимо создать класс-описание графического элемента, например, панели. Я делаю этот класс внутренним по отношению к GUIImpl , но это на любителя.

Как вы можете видеть, класс панели является наследником GUIMenuBase . Этот класс специфичен для вашего пользовательского интерфейса. Приведу мою базовую функциональность.

IGUIMenu содержит методы для работы с различными элементами. Я привел интерфейс работы только с кнопками. Далее реализуем действие, по клику на кнопки.

В принципе это все. Остается лишь реализовать класс GUILogic , которой содержит логику работы панелей. Затем открываем редактор, находим наш объект для управления пользовательским интерфейсом и назначаем элементы различных панелей соответствующим полям. Таким образом, для каждой панели должен быть свой класс, который содержит все необходимые поля. Пожалуйста, обратите внимание на поле public GameObject Instance; класса GUIMenuBase . Instance - это объект самой панели. Для большинства операций с панелью нам понадобиться ее корневой элемент.

11 1 1 золотой знак 2 2 серебряных знака 8 8 бронзовых знаков


49.4k 72 72 золотых знака 249 249 серебряных знаков 480 480 бронзовых знаков @Expert ♦♦ Воу! Ну вы даёте. Я ожидал в лучшем случае лишь поверхностных объяснений в один-два абзаца, а вы мне реальный пример привели :) Чувствую, долго я буду разбираться. Но спасибо :) В PHP как-то оно попроще было :D Кстати, вы, случаем, уроков не даете / ютуб канал не ведете по Unity?) Или хотя бы блог?) Чувствую, многому могли бы научить :) @JerryGreen, Буду рад ответить на ваши вопросы по Unity на форуме.

MVC в Юнити однозначно не нужен, как и DI. Он в принципе под это не заточен. В Юнити нет моделей, контроллеров, вьюшек, точек входа, контекстов. В Юнити есть GameObject, на который добавляются Components. Мы можем обратиться к любому объекту по ссылке на GameObject и получить с него любой компонент через GetComponent<>

С большой натяжкой можно сказать, что View (отображение в сцене) -- это GameObject с компонентами MeshFilter+MeshRenderer, а Controller (поведение) и Model (данные) - это скрипты, отвечающие за его логику. Ну ещё в качестве Model может выступать ScriptableObject (специальный тип ассета для хранения данных).

Более того, в Юнити даже ООП толком не используется, так как вы можете создавать префабы / варианты префабов, и комбинируя на них разные скрипты, меняя их значения в инспекторе, добиваться разного поведения безо всякого наследования и полиморфизма. Наследование тяжело поддерживать, а провести декомпозицию на компоненты, и поменять один компонент на другой -- не проблема.

Умоляю, не используйте бездумно "паттерны" ради архитектурных изысков, потому что потом приходится копаться в чужом проекте и пытаться понять, "что хотел сказать автор". Я попадал на проекты, где пытались применять Zenject, Entitas или MVC, и это был кошмар для разработчика.

Юнити не следует паттернам не потому что "тяп-ляп и в продакшн", как несправедливо заметил кто-то выше, а потому что у него свои собственные удобные инструменты и богатое API, не такое как в веб-разработке или нативной разработке. Потрудитесь их изучить, прежде чем садиться писать код.

Если хотите хороший пример, как правильно организовывать проект в Юнити -- посмотрите, например, замечательный 3D Game Kit. Никаких MVC, никаких инъекций зависимостей, но код чистый, проект легок для понимания, компоненты взаимозаменяемы, и на его основе легко что-то свое собрать.

Обычно скрипт в проекте содержится как файл исходного текста и компилируется Юнити при изменении. Однако также возможно компилировать скрипт в динамически связываемую библиотеку (dll) используя внешний компилятор. Результирующая dll может быть затем добавлена к проекту, а содержащиеся в ней классы прикреплены к объекту как обычные скрипты.

Создание dll

Путь к dll Юнити обычно такой

На Виндовс dll могут быт myfqltys в папках, принадлежащих приложению Юнити. Путь обычно такой

Использование dll

После компиляции dll файл может быт просто перетащен в Юнити проект как и любой другой ассет. Dll ассет имеет треугольник раскрывающий содержимое файла для выбора отдельного класса внутри библиотеки. Классы, которые были унаследованы от MonoBehaviour могут быть перетащены на ГеймОбъект как обычные скрипты. Не MonoBehaviour классы могут быт использованы прямо из других скриптов обычным путем.

Развернутая dll с классами в ней

Развернутая dll с классами в ней

Пошаговое руководство для MonoDevelop и Visual Studio

В этой секции вы узнаете как собрать и интегрировать простую dll с использованием MonoDevelop и Visual Studio, и как подготовить отладочную сессию для этой DLL.

Настройка проекта

Затем нужно заполнить информацию о новой библиотеке:

  • Name это пространство имен (в этом примере, используйте “DLLTest” в качестве названия).
  • Location это корневая папка проекта.
  • Solution name это папка проекта (название solution).

На данном этапе, у вас будет возможность выбрать нужный DLL файл. В Mac OSX, файл можно найти в

Для этого примера, переименуем класс в “MyUtilities” в Solution browser, и заменим его код на следующее:

Закончив с кодом, соберите проект, и сгенерируйте DLL файл с отладочными символами.

Читайте также: