🎮 10 самых распространенных ошибок Unity-разработчиков
Попробуем разобраться как преодолеть наиболее распространенные проблемы и избежать фундаментальных ошибок в новых или существующих проектах на Unity.
Unity – отличный простой инструмент кроссплатформенной разработки. Движок можно использовать для создания 3D- и 2D-приложений, игр виртуальной и дополненной реальности, а также для компьютерного моделирования. Попробуем разобраться, как преодолеть наиболее распространенные проблемы и избежать фундаментальных ошибок в ваших новых или существующих проектах. Обратите внимание, что эта статья больше ориентирована на разработку 3D-приложений.
Ошибка № 1: недооценка фазы планирования
Для каждого проекта важно составить план до начала разработки приложений. В нем нужно описать бизнес-модель продукта, для каких платформ он предназначен, а также задать минимальные характеристики поддерживаемых устройств. Необходимо заранее настроить весь рабочий процесс создания активов и моделей. У вас должно быть четкое представление о желаемой частоте кадров, чтобы 3D-художник мог знать, в каком максимальном разрешении можно работать. Также следует согласовать масштаб и процесс импорта во всем приложении. В противном случае вы потратите драгоценные ресурсы на труднодостижимые не обозначенные цели.
Ошибка № 2: работа с неоптимизированными моделями
Очень важно, чтобы все ваши модели были хорошо подготовлены для использования в сценах без дальнейших модификаций. При проблемах с установкой масштаба задайте коэффициент масштабирования в настройках импорта моделей (0,01 для 3dsMax и Modo или 1,0 для Maya): настройка должна гарантировать согласованное поведение моделей и отсутствие проблем с физикой. Это правило также следует применять к каждому подобъекту модели, а не только к основному. Настраивайте размеры объекта в приложении для 3D-моделирования, а не в Unity.
Ваши модели должны быть хорошо разделены. Чем меньше подобъектов, тем лучше. Каждый объект и его подобъекты должны иметь правильно выровненную и повернутую в соответствии с их основной функцией опору. У основного объекта ось Z должна быть направлена вперед, а точка поворота должна располагаться внизу объекта для лучшего размещения на сцене. Все активы должны иметь имена собственные, которые легко описывают его тип и функциональность. Сохраняйте эту последовательность во всех проектах.
Ошибка № 3: построение взаимозависимой архитектуры кода
Прототипировать и реализовать функционал в Unity довольно просто. Вы можете использовать любые объекты, обратиться к каждому из них в сцене и получить доступ к любому компоненту. Однако это создает и потенциальную опасность того, что части кода будут полностью зависеть друг от друга. Постарайтесь использовать модульный подход и создавать повторно используемые части, которые можно использовать в других частях вашего приложения.
Ошибка № 4: игнорирование потерь производительности
Есть много вещей, которые можно оптимизировать:
- Вместо обновления используйте кеширование. Типичный пример – доступ к компонентам в сцене или интенсивные вычисления в скриптах. Кешируйте все при помощи метода
Awake()
или измените архитектуру, чтобы запускать эти вещи если они необходимы. - Используйте методы отсечения окклюзии (
occlusion culling
– функция, отключающая рендеринг объектов, которые в данные момент не видит камера) или LOD (Level of Detail
– скрипт уровня детализации), чтобы ограничить визуализируемые части сцены. Используйте оптимизированные модели. - Попробуйте уменьшить количество вызовов отрисовки (
draw calls
). Используйте статическую пакетную обработку для неподвижных объектов и динамическую пакетную обработку – для движущихся. Однако вы должны сначала подготовить сцены и модели (пакетные объекты должны использовать одни и те же материалы), а пакетирование динамических объектов работает только для моделей с низким разрешением. Необходимо использовать более высокое разрешение текстур световых карт сцены (не сгенерированное разрешение, а разрешение вывода текстуры), чтобы уменьшить их количество, когда вы делаете свет в более крупных средах. - Не используйте прозрачные текстуры, когда в этом нет необходимости, так как это вызовет проблемы со скоростью их заполнения. Их можно использовать для сложной и удаленной геометрии, например, для деревьев или кустов.
- Оптимизируйте шейдеры для повышения производительности. Уменьшите количество проходов, используйте переменные с меньшей точностью, замените сложные математические вычисления предварительно созданными текстурами поиска. Всегда применяйте профилировщик для определения узких мест, а также пользуйтесь инструментом отладки Frame Debugger.
Ошибка № 5: игнорирование проблем со сборкой мусора
Хотя Garbage Collector (сборщик мусора) – довольно полезная штука, есть несколько вещей которые, нужно четко усвоить. Следует избегать ненужного выделения памяти, чтобы сборщик мусора не запускался слишком часто и не снижал производительность из-за скачков частоты кадров. Все это определяется архитектурой приложения, но есть несколько правил, которым нужно следовать:
- Избегайте лишних затрат на обновления.
- Используйте простые структуры.
- Попробуйте предварительно выделить массивы, списки или другие коллекции объектов вместо того, чтобы создавать их внутри циклов обновления.
- Избегайте моно-проблемных вещей (например, выражений LINQ или циклов foreach), потому что Unity использует старую версию Mono (платформы разработки с открытым исходным кодом, основанную на .NET).
- Если необходимо обновление свойства строки в цикле, используйте объект StringBuilder.
- Используйте профилировщик для выявления потенциальных проблем.
Ошибка № 6: оптимизируйте использование памяти и пространств
Для поиска источников слива ресурсов вы можете использовать журнал редактора. Там после каждой новой сборки виден размер разделенных на отдельные категории ресурсов: аудио, текстур и библиотек. Для лучшей ориентации в Unity Asset Store есть расширения редактора, предоставляющее подробную сводку со ссылками на ресурсы и файлы. Фактическое потребление памяти также можно увидеть в профилировщике, но рекомендуется протестировать его при подключении к сборке на вашей целевой платформе. Самыми большими потребителями памяти часто являются текстуры. Желательно использовать сжатые и повторяющиеся текстуры, так как они занимают гораздо меньше места.
Ошибка № 7: общие ошибки физики
Перемещая объекты в сцене, помните о наличии коллайдера (базового примитива столкновений) и что изменение его положения заставит движок пересчитать весь физический мир заново. В этом случае вы должны добавить к нему компонент Rigidbody.
Используйте примитивные коллайдеры для таких игровых объектов, как сфера, прямоугольник или цилиндр. Физика может быть узким местом производительности приложения из-за нагрузки на процессор, а столкновения между примитивными коллайдерами вычисляются гораздо быстрее. Вы также можете настроить параметр Fixed Timestep в диспетчере времени, чтобы уменьшить частоту фиксированных обновлений физики, когда точность взаимодействия не так необходима.
Ошибка № 8: тестирование всей функциональности вручную
Можно проверять функциональность вручную разово для какой-то одной операции, экспериментируя в режиме воспроизведения. Однако чем сложнее приложение, тем сложнее и серьезнее отладка. В Unity есть отличные инструменты для тестирования. При соответствующей архитектуре и дизайне кода вы можете использовать модульные тесты для изолированной функциональности или даже интеграционные для тестирования более сложных сценариев, значительно сократив количество проб и проверок. Ручное тестирование, без сомнения, является важной частью разработки, но все должно быть в меру.
Ошибка № 9: работа только с плагинами Unity Asset Store
Если желаемую функциональность нетрудно реализовать, просто добавьте ее в личные (или корпоративные) библиотеки, которые впоследствии снова можно будет использовать во всех проектах. Таким образом вы одновременно улучшите свои знания и расширите набор инструментов.
Ошибка № 10: не расширять базовую функциональность
Иногда может показаться, что среды Unity Editor вполне достаточно для базового тестирования игры и проектирования уровней, а ее дополнения – пустая трата времени. Это далеко не так. Большой потенциал расширений Unity заключается в возможности адаптировать их к конкретным задачам, которые необходимо решать в различных проектах. Это улучшит взаимодействие с пользователем и ускорит рабочий процесс проектирования уровней. Используйте встроенные или настраиваемые ящики свойств, ящики декораторов, инспектор настраиваемых компонентов или создавайте собственные плагины в окне редактора.
Самое важное – поддерживать единообразие идиом на протяжении всего проекта, чтобы бы у вас сформировался собственный стиль разработки на Unity. Надеемся, прочитав эту статью, вы сделали правильные выводы. Удачи.