Kav-soft.ru

ПК Софт
6 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Оптимизация игры unity

Методы оптимизации при разработке в Unity 3D

  • Рассказы о своих проектах, 8 марта 2013 в 16:24
  • Саша

Евгений Семушин, руководитель компании по разработке программного обеспечения EcmaSoft

Производительность имеет решающее значение для мобильных игр. Особенно если игра сочетает в себе физику, AI (искусственный интеллект) и полностью анимированных персонажей 3D-мира. Некоторое время назад мы сделали игру под названием «Spearfishing 3D — подводная охота» для iOS. За первые полгода после релиза игра была скачана около двух миллионов раз и попала в топ-10 в категории «Игры» в разных странах мира. Одна из основных проблем, которую нам понадобилось решить, — обеспечение работы игры с 60 fps. Это стало проще с выпуском iPad и iPhone 4, но мы по-прежнему должны поддерживать как минимум 30 fps для iPhone 3G/3GS. В этой статье я опишу подходы, которые мы использовали для оптимизации игр на основе Unity.

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

Первое место, куда нужно смотреть, когда хочется улучшить производительность — это Unity Profiler. Эта функциональность доступна в Unity Pro и позволяет анализировать проблемные места. Профайлер — бесценный инструмент. С его помощью можно определить, где возникают проблемы с частотой кадров. Для его использования запустите игру на мобильном устройстве и профайлер на PC. Когда вы запускаете игру, профайлер начинает загружать данные о производительности.

Чтобы использовать профайлер на мобильных устройствах, сделайте билд в Developer mode. Из документации Unity:

Чтобы иметь возможность подключиться к плееру, плеер должен быть запущен с помощью опции Development Build, которая находится в диалоговом окне Build Settings.

Здесь также можно отметить флажок для автоматического соединения редактора и плеера. Профайлер показывает график использования CPU во время игры. Просто подключите мобильное устройство к машине для разработки и проходите игру. Профайлер покажет все проблемы в режиме реального времени. Он разбивает активности на Rendering, Scripts, Physics, GarbageCollector, VSync и другие. В мобильных играх часто бывают проблемы с рендерингом. Иногда скачки производительности возникают в скриптах при загрузке сцены, но в этом нет ничего необычного. Некоторые скачки связаны с физикой.

Физика и искусственный интеллект

Я опишу несколько основных идей оптимизации кода физики и перейду к графике.

  • Старайтесь, чтобы как можно меньше объектов двигалось одновременно. «Спящие» объекты намного дешевле.
  • То же самое касается искусственного интеллекта. Если объект находится далеко от главного героя или его не видно, не запускайте скрипты искусственного интеллекта.
  • Рейкасты очень дорогие. Не делайте рейкаст на каждый фрейм — попробуйте кэшировать результаты и пропустить некоторые фреймы.
  • Старайтесь избегать сложных меш коллайдеров.
  • Проверьте функции Update() . Они запускают каждый кадр и, следовательно, дорогие. Вместо этого используйте Coroutines .

Static batching

Это фича Unity, которая экономит много циклов CPU. Каждый раз, когда объект рендерится, происходит Draw Call — команда для CPU или GPU о том, что объект должен отрендериться. Unity запускает несколько вызовов отрисовки и накладывает их друг на друга, это и формирует сцену. Однако каждый Draw Call требует ресурсов CPU, поэтому мы хотим минимизировать их количество.

Тут и стоит использовать Batching. Он нужен для того, чтобы не делать лишние Draw Calls. Batching бывает двух видов: статический и динамический. Статический дает лучшую производительность, поэтому мы всегда стараемся использовать его.

Ивент переехал в онлайн, есть новые даты ( 14 – 15 июля ) , Москва и онлайн, 10 750–138 000 ₽

Чтобы эффективно применять Static Batching, используйте как можно меньше различных материалов. Для этого скомбинируйте все материалы в одну большую текстуру. Последний шаг — добавить Lightmap к сцене. Поскольку мы практически не используем память для текстуры объектов, можно сделать довольно подробную Lightmap, и проблем с памятью не возникнет.

Для использования Static Batching поставьте флажок Static в свойствах объекта. Его можно использовать только для объектов, которые не перемещаются, не вращаются и не масштабируются в сцене.

Dynamic Batching

Для не статических объектов можно использовать Dynamic Batching. Объекты с Dynamic Batching требуют определенные ресурсы на каждую вершину, поэтому он применяется только к мешам, содержащим менее 900 вершин. Наш шейдер использует Vertex Position, UV и Colors. Таким образом, у нас может быть до 300 вершин на объект.

Некоторые полезные советы из руководства Unity:

  • Динамический батчинг связан с дополнительной нагрузкой для каждой вершины, так что он применим только к мешам, в сумме содержащим менее 900 вершин.
  • Если ваш шейдер использует Vertex Position, Normal и единственный UV, то вы можете батчить до 300 вершин; тогда как если шейдер использует Vertex Position, Normal, UV0, UV1 и Tangent, то только 180 вершин.
  • Не масштабируйте. Объекты с масштабом (1,1,1) и (2,2,2) не будут батчиться.
  • Равномерно масштабированные объекты не будут батчиться с неравномерно масштабированными.
  • Использование различных материалов приведет к сбою батчинга.
  • Объекты с Lightmap имеют дополнительный (скрытый) параметр материала: смещение/масштаб в Lightmap, поэтому объекты с Lightmap не будут батчиться.

Заметьте: если у объекта есть анимация, но при этом есть часть, которая никогда не двигается, можно отметить эту часть как статическую, и она не будет мешать анимации.

Оптимизация 2D игр на Unity

Обновленная версия статьи всегда по адресу: https://mopsicus.ru/all/optimization-unity-2d-games/

На Youtube куча уроков по созданию простейших 2D игр на Unity. Реально, сделать неплохой платформер можно за день, при наличии опыта и готовых ассетов. Но многие начинающие игроделы сделав проект и протестировать его на ПК, с ужасом наблюдают как их творение тормозит на мобильном устройстве.

В мануалах, что встречаются в сети, большинство советов собрано к версии Unity 4.6+, кроме того, они почти все на английском, что для некоторых является преградой. В этом посте, я постарался собрать те моменты, которые помогли мне избавится от лагов на iOS и Android. Но важно понимать — не все можно решить лишь настройками, очень важна и архитектура приложения, и подготовленные текстуры, и знание более оптимальных алгоритмов.

Что нужно предпринять, чтобы повысить производительность, поднять FPS, снизить CPU?

1. Кешируем все!

Все, что будет использоваться больше одного раза лучше закешировать. Операции типа GameObject.Find() или GetComponent() достаточно ресурсозатратны, а если они вызываются где-нибудь в цикле или в Update (), то производительность может упасть.

void Awake () <
_cachedTransform = transform;
>
void Update () <
_cachedTransform.localPosition = _newPosition;
>

2. Настройки графики

В Unity есть 6 стандартных пресетов настройки качества графики. Но так как мы говорим про оптимизацию для 2D и для мобильных устройств, то все что выше Simple нет смысла ставить. Конечно, если у вас есть какие-то специфические моменты, частицы, и т. д., то с параметры можно поэкспериментировать найдя оптимальный баланс.

3. Используем FrameRate

По-умолчанию FrameRate равен 30. И зачастую этого бывает достаточно. Но например, при создании UI где есть прокручивающие списки и движущие элементы, может появится дрожание или шлейф. Я это заметил при тестировании на iPhone, поэтому вручную повысил FrameRate. А понижая FrameRate на сценах или игровых меню, где ничего не двигается, можно значительно снизить CPU, а следовательно продлить жизнь батарее устройства. Пользователи не любят когда игра сжирает аккумулятор за час.

public int _frameRate = 60;

void Start () <
# if UNITY_IOS
QualitySettings.vSyncCount = 0;
# endif >

void Update () <
# if UNITY_IOS
if (_frameRate != Application.targetFrameRate) <
Application.targetFrameRate = _frameRate;
>
# endif
>

4. Атлас текстур

Определенно, нужно упаковывать все свои спрайты в атласы. Для этого есть как встроенный инструмент Sprite Packer , так и продвинутый TexturePacker . Для работы встроенного упаковщика, достаточно задавать теги в настройках импорта, объединяя текстуры и спрайты по смыслу и месту использования.

Таким образом уменьшается количество вызовов отрисовок ваших спрайтов. Проверить как идет отрисовка можно с помощью встроенного инструмента Frame Debugger .

5. Используем пул объектов

GameObject.Instantiate () — очень дорогая операция! Если есть возможность не использовать ее в процессе игры — не используйте. Для большого количества однотипных объектов надо использовать пул объектов. Один раз инициализировав определенное количество, например пуль, они будут использоваться снова и снова, вместо создания и уничтожения каждый раз. Урок по пулу объектов и готовый шаблон , для начала будет достаточно.

6. Меньше Update — больше событий

Метод Update () вызывается каждый кадр, FixedUpdate () в некоторых случаях еще чаще. Если у вас в этих местах происходит много различных проверок и действий, это можно сказаться на производительности. Я использую событийную модель: вместо проверки условия в Update (), когда происходит какое-либо действие, отправляется событие, а в нужном месте это событие «слушается» и обрабатывается в зависимости от переданных параметров. Для этого можно использовать менеджер событий о котором я писал ранее.

7. Выключаем неиспользуемые компоненты

Деактивируйте объекты которые не попадают в камеру и которые не видно на сцене. Это также повысит производительность. Можно использовать вот такой хак, чтобы автоматически деактивировать объекты которые выходят за определенные границы.

8. Настройки билда

Билд под конкретную платформу, тоже можно оптимизировать. Например, если акселерометр не используется в игре, его лучше вообще отключить. Кроме того, я не использую автовыбор графического API, а задаю его сам убирая все остальные, опять же, если вы не используете какие-то специфические функции из OpenGLES 3.0, а так второй версии вполне хватает, она уже давно протестирована. Включаем статичный и динамический батчинг, а для Android многопоточный рендеринг. Для iOS включаем Script Call Optimization в Fast but no Exceptions, но тут момент — если будет какое-то исключение, то игра крашится.

9. Используем Profiler

Не стоит обделять вниманием профайлер. Обязательно протестируйте свою игру и посмотрите, в какие моменты идет максимальная нагрузка. Эти места нужно оптимизировать в первую очередь. Большинство ответов можно найти на stackoverflow.com или форуме Unity, просто загуглив название метода который тратит больше всего ресурсов.

10. Использование материала для UI Image и SpriteRenderer

Если у вас сложный интерфейс и много компонентов, особенно UI Image, то они существенно будут влиять на FPS. Чтобы повысить производительность, улучшить плавность анимаций, можно применить такой хак: там где вы не используете маски, у картинок нужно задать материал Sprites-Default . Если это сделать вместе с маской, то маска не сработает и получите примерно такой варнинг:

Material Sprites-Default doesn’t have _Stencil property

Чтобы убрать эту ошибку нужно немного изменить стандартный шейдер, сделать новый материал и применить его там где есть маска, тогда все сработает. Ссылка на измененный шейдер.
Цена плавности — повышение CPU 🙁

11. Уменьшаем размер текстур

Отличная утилита которая позволяет снизить потребления памяти для текстур до 3х раз. Как это работает и ссылка на Github, в статье на Хабре.

12. Практическое руководство по оптимизации Unity игр

Подойдет как для 2D, так и для 3D. Много полезной информации которую в документации вряд ли найдешь. Тут и про инструменты, и про опыт. Рассказывает специалист по эксплуатации из Unity Technologies — очень интересно. Узнал про memory profiler и то, что Camera.main не закеширована О_О. Обязательно смотреть всем.

13. Используем оптимизированный код

Снова хочется посоветовать набор оптимизированных скриптов от Leopotam. Коллекции, сериализация, векторы и многое другое. Настоятельное рекомендую, к изучению и использованию.

14. Используем одинаковые материалы

Если на объектах стоят разные материалы, они не будут батчится и будет больше вызовов отрисовки. Соответственно, нужно по возможности использовать как можно меньше разных шейдеров и материалов. Для понимания, как работает начальная оптимизация графики 2D, на Lynda.com есть небольшой курс .

15. Размеры атласов и спрайтов

Для применения сжатия спрайтов на мобильных устройствах нужно использовать атласы с размерами кратными степени 2, т. е. 1024х1024, 2048х2048.

16. Используйте UI Profiler

В Unity 2017 появился UI Profiler! Крутая штука, теперь можно выяснить почему в интерфейсе много вызовов отрисовки, увидеть какие материалы на объектах и всё это оптимизировать. Особенно актуально, если у вас сложные интерфейсы со множеством элементов, которые например, прокручиваются в ScrollRect.

17. Уголок оптимизатора

На сайте Unity появился специальный раздел посвященный оптимизации — Optimization corner . Там и про UI, и профайлеры, и основные ошибки, в общем, стоит ознакомиться.

Пока все. Тут не было про физику, потому что пока я ее не использовал. Возможно, в будущем добавлю.
__________________________________________________________________________________________

Все последние обновления этой и других статей, вы можете найти у меня в блоге https://mopsicus.ru

Подписывайтесь, чтобы не пропустить что-то интересное

Unity оптимизация CPU поехали

Привет. Портруем игру на iOS ( все не так плохо ) и Android ( полный ужас )

Хотел бы поднять тему с шашлыком, и вашим опытом оптимизации CPU что, где, когда и сколько миллисекунд)

Есть ли смысл загонять объекты в свой список, и оттуда вызывать FixedUpdate — т.е. будет ли это быстрее вызова из юнити — если таких вызовов много?

Так же — в профайлере Physics.UpdateBodies кушает достаточно много время, если ли смысл выключать коллайдеры ручками на расстоянии ? ( в буллете раньше мы так делали C++)

  • zlos
  • Удалён

Выглядит так будто слишком много всего рендерится и слишком много физики.

  • foxes
  • Постоялец

Сегментируй данные, разделяй их обработку порционно, даже можно сделать не на каждый кадр. Не знаю какие алгоритмы ты используешь но например, поиск путей вообще нет смысла пересчитывать по клику или для каждого объекта для одной и той же цели. То есть многие результаты расчетов могут использовать для различных задач. Тем самым используя уже посчитанные данные в одном случае можно применить их результат на разных этапах к другим. В итоге можно разгрузить CPU раз в 100-1000, а может и все 100%. Большинство объектов можно действительно не удалять, а преобразовывать их в нужный объект или хранить про запас, тем самым разгрузить GerbageCollector. Для «Physics» есть еще один прием помимо выключения коллайдеров, это сегментировать область их действий — разделять пространство на слои, тогда автомат быстрее сообразит что с чем столкнется. Для Rendering больше всего проблем с анимированными моделями, так же сократить количество обновлений, или отказаться от Skin модификаторов. Только трансформационная анимация отдельных объектов/елементов. Ну и конечно же не забывать о простых шейдерах и общих текстурных атласах заменяющих расчеты в них. В общем все сводиться к более жесткому определению и выделению статических данных.

FDsagizi
> Есть ли смысл загонять объекты в свой список, и оттуда вызывать FixedUpdate —
> т.е. будет ли это быстрее вызова из юнити
Есть смысл обрабатывать дочерние объекты в родительском FixedUpdate. Не создавая ни каких списков и не вызывая на каждый Child свой FixedUpdate. Также не загружать большое количество объектов компонентами, а использовать всего на одном родительском. Очень большой профит будет от оптимизации полученного цикла в родительском обработчике — в конечном итоге это будет замена на векторную обработку, фиксированного количества дочерних объектов (опять же сегментация обработки данных, хранение не используемых объектов про запас).

  • FDsagizi
  • Постоялец

zlos
> Выглядит так будто слишком много всего рендерится и слишком много физики.
Рендериться да. Физики много но вся спит

Проверил — отключение статичной физики и спящих объектов на растонии ничего не меняет — Physics молодец!

#mopsicus

Оптимизация 2D игр на Unity

Этот пост будет периодически дополняться и обновляться.
Обновлено 28.11.2019

На Youtube куча уроков по созданию простейших 2D игр на Unity. Реально, сделать неплохой платформер можно за день, при наличии опыта и готовых ассетов. Но многие начинающие игроделы сделав проект и протестировать его на ПК, с ужасом наблюдают как их творение тормозит на мобильном устройстве.

В мануалах, что встречаются в сети, большинство советов собрано к версии Unity 4.6+, кроме того, они почти все на английском, что для некоторых является преградой. В этом посте, я постарался собрать те моменты, которые помогли мне избавится от лагов на iOS и Android. Но важно понимать — не все можно решить лишь настройками, очень важна и архитектура приложения, и подготовленные текстуры, и знание более оптимальных алгоритмов.

Что нужно предпринять, чтобы повысить производительность, поднять FPS, снизить CPU?

1. Кешируем все!

Все, что будет использоваться больше одного раза лучше закешировать. Операции типа GameObject.Find() или GetComponent() достаточно ресурсозатратны, а если они вызываются где-нибудь в цикле или в Update (), то производительность может упасть.

Не используйте Resources.Load () каждый раз когда нужно в рантайме загрузить что либо, это тоже дорогая операция. Лучше при старте закешировать и работать с кешем. Ну и конечно, объединяйте в префабы.

2. Настройки графики

В Unity есть 6 стандартных пресетов настройки качества графики. Но так как мы говорим про оптимизацию для 2D и для мобильных устройств, то все что выше Simple нет смысла ставить. Конечно, если у вас есть какие-то специфические моменты, частицы, и т. д., то с параметры можно поэкспериментировать найдя оптимальный баланс.

3. Используем FrameRate

По-умолчанию FrameRate равен 30. И зачастую этого бывает достаточно. Но например, при создании UI где есть прокручивающие списки и движущие элементы, может появится дрожание или шлейф. Я это заметил при тестировании на iPhone, поэтому вручную повысил FrameRate. А понижая FrameRate на сценах или игровых меню, где ничего не двигается, можно значительно снизить CPU, а следовательно продлить жизнь батарее устройства. Пользователи не любят когда игра сжирает аккумулятор за час.

4. Атлас текстур

Определенно, нужно упаковывать все свои спрайты в атласы. Для этого есть как встроенный инструмент Sprite Packer, так и продвинутый TexturePacker. Для работы встроенного упаковщика, достаточно задавать теги в настройках импорта, объединяя текстуры и спрайты по смыслу и месту использования.

Таким образом уменьшается количество вызовов отрисовок ваших спрайтов. Проверить как идет отрисовка можно с помощью встроенного инструмента Frame Debugger.

5. Используем пул объектов

GameObject.Instantiate () — очень дорогая операция! Если есть возможность не использовать ее в процессе игры — не используйте. Для большого количества однотипных объектов надо использовать пул объектов. Один раз инициализировав определенное количество, например пуль, они будут использоваться снова и снова, вместо создания и уничтожения каждый раз. Урок по пулу объектов и готовый шаблон, для начала будет достаточно.

6. Меньше Update — больше событий

Метод Update () вызывается каждый кадр, FixedUpdate () в некоторых случаях еще чаще. Если у вас в этих местах происходит много различных проверок и действий, это можно сказаться на производительности. Я использую событийную модель: вместо проверки условия в Update (), когда происходит какое-либо действие, отправляется событие, а в нужном месте это событие «слушается» и обрабатывается в зависимости от переданных параметров. Для этого можно использовать менеджер событий о котором я писал ранее.

7. Выключаем неиспользуемые компоненты

Деактивируйте объекты которые не попадают в камеру и которые не видно на сцене. Это также повысит производительность. Можно использовать вот такой хак, чтобы автоматически деактивировать объекты которые выходят за определенные границы.

8. Настройки билда

Билд под конкретную платформу, тоже можно оптимизировать. Например, если акселерометр не используется в игре, его лучше вообще отключить. Кроме того, я не использую автовыбор графического API, а задаю его сам убирая все остальные, опять же, если вы не используете какие-то специфические функции из OpenGLES 3.0, а так второй версии вполне хватает, она уже давно протестирована. Включаем статичный и динамический батчинг, а для Android многопоточный рендеринг. Для iOS включаем Script Call Optimization в Fast but no Exceptions, но тут момент — если будет какое-то исключение, то игра крашится.

9. Используем Profiler

Не стоит обделять вниманием профайлер. Обязательно протестируйте свою игру и посмотрите, в какие моменты идет максимальная нагрузка. Эти места нужно оптимизировать в первую очередь. Большинство ответов можно найти на stackoverflow.com или форуме Unity, просто загуглив название метода который тратит больше всего ресурсов.

10. Использование материала для UI Image и SpriteRenderer

Если у вас сложный интерфейс и много компонентов, особенно UI Image, то они существенно будут влиять на FPS. Чтобы повысить производительность, улучшить плавность анимаций, можно применить такой хак: там где вы не используете маски, у картинок нужно задать материал Sprites-Default. Если это сделать вместе с маской, то маска не сработает и получите примерно такой варнинг:

Material Sprites-Default doesn’t have _Stencil property

Чтобы убрать эту ошибку нужно немного изменить стандартный шейдер, сделать новый материал и применить его там где есть маска, тогда все сработает. Ссылка на измененный шейдер.
Цена плавности — повышение CPU 🙁

11. Уменьшаем размер текстур

Отличная утилита которая позволяет снизить потребления памяти для текстур до 3х раз. Как это работает и ссылка на Github, в статье на Хабре.

12. Практическое руководство по оптимизации Unity игр

Подойдет как для 2D, так и для 3D. Много полезной информации которую в документации вряд ли найдешь. Тут и про инструменты, и про опыт. Рассказывает специалист по эксплуатации из Unity Technologies — очень интересно. Узнал про memory profiler и то, что Camera.main не закеширована О_О. Обязательно смотреть всем.

13. Используем оптимизированный код

Снова хочется посоветовать набор оптимизированных скриптов от Leopotam. Коллекции, сериализация, векторы и многое другое. Настоятельное рекомендую, к изучению и использованию.

14. Используем одинаковые материалы

Если на объектах стоят разные материалы, они не будут батчится и будет больше вызовов отрисовки. Соответственно, нужно по возможности использовать как можно меньше разных шейдеров и материалов. Для понимания, как работает начальная оптимизация графики 2D, на Lynda.com есть небольшой курс.

15. Размеры атласов и спрайтов

Для применения сжатия спрайтов на мобильных устройствах нужно использовать атласы с размерами кратными степени 2, т. е. 1024х1024, 2048х2048.

16. Используйте UI Profiler

В Unity 2017 появился UI Profiler! Крутая штука, теперь можно выяснить почему в интерфейсе много вызовов отрисовки, увидеть какие материалы на объектах и всё это оптимизировать. Особенно актуально, если у вас сложные интерфейсы со множеством элементов, которые например, прокручиваются в ScrollRect.

17. Уголок оптимизатора

На сайте Unity появился специальный раздел посвященный оптимизации — Optimization corner. Там и про UI, и профайлеры, и основные ошибки, в общем, стоит ознакомиться.

18. Несколько советов по оптимизации UI

Раннее уже упоминали про Camera.main, но в новой статье описаны ещё несколько интересных особенностей оптимизации UI.

19. Сборник советов от FunCorp

Хорошая статья про оптимизацию UI. Многое уже описано тут, но есть и замечания по новым компонентам, например TextMeshPro.

20. Оптимизация UI без кода

Статья от Banzai Games про основные способы не делать неправильно Unity UI. Есть и интересные замечания. Зачем только снова про древний текстовый компоненты говорить. Думаю уже все перебрались на TMP.

Пока все. Тут не было про физику, потому что пока я ее не использовал. Возможно, в будущем добавлю. Пишите в комментариях ваши проверенные способы оптимизации для 2D игр под Unity.

Оптимизация игры unity

При разработке игры ,можно столкнуться с проблемой оптимизации, когда даже при относительно не большом количестве полигонов и без использования каких либо эффектов, игра притормаживает даже на топовых устройствах. Это может быть из-за того, что в сцене много мелких объектов и они в разы увеличивают Draw Calls, с этой проблемой можно справиться путем объединения всех объектов с одним материалом в один Mesh, через встроенную в Unity функцию, которая находится по следующему пути: Component/Mesh/Combine Children, подробнее о ней будет чуть ниже.

В общем ниже будут перечислены основные приемы оптимизации игр в Unity.

Несколько советов по снижению Draw Calls (Draw Calls — количество обращений CPU к GPU)

1. Использовать как можно меньше текстур и материалов. Желательно, чтобы как можно больше объектов использовало один и тот же материал. Один и тот же материал может быть использован на объектах двумя способами: через renderer.material и renderer.sharedMaterial. В первом случае получается независимая копия материала, свойства которой можно менять без изменения тех же свойств на остальных объектах. Батчится же будут только меши, на которые наложены материалы через sharedMaterial. Материал, который вешается через редактор, по умолчанию вешается именно на sharedMaterial.
Но тут есть одно но — в каждом меше должно быть Mesh -> Combine Children.

Правильное использование музыки в игре:

1. Если фоновая музыка одна, то вполне уместно не упаковывать трек в памяти и читать его после старта сцены.
Фоновую музыку исключительно стримить с ресурсов и исключительно в MP3 (мало занимает места, хорошо стримится). Короткие звуки можно перегнать в ogg для уменьшения времени распаковки и распаковывать в памяти, либо стримить с ресурсов — по обстоятельствам. Так же необходимо понимать, что не все источники будут слышны одновременно на мобилках так, как они слышны в редакторе. На части устройств (смарты) при количестве AudioSource > 4 появлялся визг с хрипом, а так же ощутимые лаги, на части прекрасно работало (планшеты). Для себя принял решение держаться в рамках максимум 4-ех проигрываемых звуков. WAV — не использовать никогда.

1. Использовать только 1 источник света для освещения, затемнения отдельных частей карты лучше использовать Lightmap`ы
2. Старайтесь как можно реже, или вообще не использовать объекты с Rigidbody
3. Fog — дает сильную нагрузку
4. Шейдеры для материалов, стараться использовать из категории Mobile/. — более оптимизированы

1. Использовать небольшие размеры террейна

150×150
2. Pixel Error — выставить с 0 до максимального значения ( хоть это и предаст прыгающие вершины при приближении камеры, зато в разы увеличит производительность)
3. Отключать флажок Draw
4. Не использовать отрисовку травы в инструментах Terrain`a — в разы уменьшает производительность

1. Все расчеты производить исключительно в Update. В FixedUpdate можно делать небольшие проверки, специфичные для физики, но лучше вообще избегать использования FixedUpdate. Почему? Update вызывается FPS-равное количество раз и увеличение нагрузки просто будет просаживать скорость рендеринга рывками. Это не страшно, т.к. все апдейты должны вестись с учетом Time.deltaTime. FixedUpdate выполняется равное количество раз в секунду и движок ждет завершения выполнения. В результате игру будет визуально дергать при неравномерной вычислительной нагрузке в FixedUpdate.
2. Не использовать new (типа new Vectro3(x,y,z), new Rect()) в циклах и часто вызываемых местах
3. CompareTag более чем вдвое быстрее прямой проверки тэга по имени.
4. (thisTransform.position — target.position).sqrMagnitude быстрее Vector3.Distance
5. Делайте как можно меньше вызовов thisTransform.forward или position, лучше эти значения один раз получить в Update, и использовать во всем скрипте.. Это касается любых готовых свойств MonoBehaviour, включая сам transform. Ощущение, что они всегда получаются выбором из списка компонентов, без кеширования — его нужно делать руками. Все вектора в глобальном пространстве (forward, right, up и т.п.) всегда перевычисляются при каждом обращении к ним по иерархии GameObject — надо прочитать один раз и использовать в текущем коде.
6. Для включение скрипта на объекте при возможности использовать не GetComponent(. ).enabled с заранее отключенным скриптом, а AddComponent(. )
при заранее не повешенном скрипте на объекте

7. Использование Статических переменных

При использовании JavaScript наиболее важной оптимизацией является использование статических типов вместо динамических. Unity использует метод, который называется type inference, для автоматической конвертации переменных JavaScript к статическому коду, для этого вам ничего не понадобиться делать.

В приведенном выше примере foo автоматически распознается как переменная типа integer. Таким образом Unity может применить множество оптимизаций времени компиляции, без затратных динамических поисков имени переменной и тд. Это одна из причин, почему Unity JavaScript в среднем в 20 раз быстрее чем какие либо другие реализации JavaScript.

Единственная проблема – не все типы возможно распознать, в таких случаях Unity вернётся обратно к динамическому типу для этих переменных. Использование динамических типов на JavaScript было бы проще для написания кода, тем не менее это бы замедлило его выполнение кода.

Рассмотрим несколько примеров:

В данном варианте foo будет динамически определено, таким образом вызов функции DoSomething длится дольше чем нужно, потому что тип foo неизвестен, и вначале нужно выяснить, поддерживает ли foo функцию DoSomething, и если поддерживает то вызвать её.

Здесь foo у нас имеет определённый тип. Производительность в данном случае будет гораздо лучше.

8. Используйте #pragma strict

Конечно, сейчас проблема состоит в том, что вы обычно не замечаете использование динамической вёрстки. #pragma strict сможет вам помочь. Просто добавьте в начало кода #pragma strict и Unity отключит динамическую вёрстку в данном скрипте, вынуждая вас использовать статическую. Там где тип будет неизвестен, Unity сообщит нам про ошибки компиляции. В этом случае foo будет выдавать ошибку на этапе компиляции:

9. Кешированый поиск компонентов

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

Всякий раз когда вы получаете доступ к компоненту через GetComponent или средством доступа переменной, Unity должен найти нужный компонент из игрового объекта. Время на поиск можно легко сократить если использовать кеширование ссылки на компонент в часной (private) переменной.

Просто преобразуйте этот код:

Последний вариант будет работать намного быстрее, так как Unity не нужно искать компонент Transform в игровом объекте каждый кадр.
Тоже самое применимо для скриптовых компонентов, где вы используете GetComponent вместо transform или других изменений свойств.

10. Используйте встроенные массивы

Встроенные массивы имеют очень высокую скорость работы, старайтесь использовать их когда это возможно. Хоть ArrayList или классы массивов намного проще использовать, так как в них легче производить добавление элементов, скорость работы у них ниже. Встроенные массивы имеют фиксированный размер, но в большинстве случаев размер известен нам с самого начала, и мы можем в любой момент заполнить его. Одним из важнейших достоинств встроенных массивов является то, что они непосредственно включают типы данных struct в один сильно упакованный буфер, без какой либо дополнительной информации о типе или накладных расходов. Таким образом, совершать интеракции на кеше очень легко, так как в нём всё выровнено.

11. Не делайте вызов функции, если без этого можно обойтись

Самый простейший и лучший способ оптимизации – это совершать как можно меньше лишней работы. К примеру, когда враг далеко от нас, наилучшим будет сделать так, чтобы он «заснул». То есть не совершал никаких действий пока игрок не подойдёт ближе. Вот медленный вариант реализации этого случая:

Это не самая удачная идея, так как Unity должен вызывать update функцию постоянно, а значит мы выполняем лишнюю работу каждый кадр. Наилучшим решением в данном случае будет отключение программы врага, пока игрок не подойдёт поближе. Существует 3 способа реализации этой идеи:

1) Использовать OnBecameVisible и OnBecameInvisible. Эти вызовы заложены в системе прорисовки. Как только какая-нибудь камера видит объект, вызывается OnBecameVisible, когда ни одна камера не видит его, делается вызов OnBecameInvisible. В некоторых случаях это оправдано, но иногда это проблематично для AI, так как враги становятся неактивными, когда вы отклоняете от них камеру.

2) Используйте триггеры. Простой шарообразный триггер области может творить чудеса. При выходе из выбранной нами области влияния мы получаем вызовы OnTriggerEnter/Exit.

3) Используйте Coroutines. Главным недостатком Update является то, что он исполняется каждый кадр. Вполне возможным была бы проверка расстояния до игрока каждые 5 секунд. Это бы неплохо повысило производительность.

голоса
Рейтинг статьи
Читайте так же:
Определить модель видеокарты nvidia
Ссылка на основную публикацию
Adblock
detector