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

Сцена полна батутов, некоторые из них неподвижны, а другие движутся в воздухе. Игрок находится в центре сцены, где шары появляются каждые полсекунды.

Он содержит различные источники света, и некоторые из них отбрасывают мягкие тени.

В процессе использовались HTC Vive, последняя бета-версия Unity (2017.1.1f1) и первоначальный неоптимизированный предоставленный проект.

Игра была оптимизирована примерно за 7 часов.

Оптимизации

В процессе оптимизации для выявления узких мест использовался Unity Profiler.

Дозирование

  • Включена статическая и динамическая пакетная обработка
  • Настройка неподвижных игровых объектов, чтобы они были статическими и динамическими по отношению к другим
  • Объединение во время редактирования мешей с одинаковым общим поведением и движением.

Выбраковка усеченного конуса

  • Разделение мешей, которые нужно объединить, по зонам видимости, чтобы воспользоваться преимуществами автоматического отсечения усеченной пирамиды в Unity:

связанные с виртуальной реальностью

  • Фиксированный временной шаг установлен на 0,0111111, чтобы синхронизироваться с целевой частотой кадров (90 кадров в секунду).

Физика

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

объем памяти

  • Использование шаблона проектирования пула объектов очереди для возрождаемых объектов, которые будут использоваться в игре, удаление методов Instantiate и Destroy.
  • Все объекты пула были созданы в Редакторе
  • Все сериализованные свойства были назначены в редакторе
  • Использование пула очередей также для систем частиц, которые будут использоваться в игре.

моноповедение

  • Удалены пустые методы Monobehaviours.
  • Сериализуемые ссылки на компоненты были назначены в редакторе и, следовательно, кэшированы, чтобы избежать Find, GetComponent и всех их вариантов во время выполнения.

Обнаружение ошибки

  • Добавлены утверждения для быстрого определения неназначенных сериализованных ссылок в редакторе на компоненты в начале игры.

Коммуникация

  • Использование шаблонов наблюдателя и обмена сообщениями, чтобы избежать ненужных проверок изменений в других объектах.

Трансформировать

  • Убрано избыточное перемещение трансформаций в методе Update объектов с одинаковым шаблоном перемещения, группируя их и используя затем только одно общее движение
  • Сбрасывайте масштаб, когда это возможно, чтобы избежать возможных ошибок из-за компьютерного численного анализа (ограничения использования мантиссы в представлениях чисел с плавающей запятой)

Удаление лишнего веса

  • Удалены Debug.Logs

Освещение

  • Настройка пути рендеринга для использования прямого рендеринга вместо отложенного освещения, потому что это лучший выбор для требований этого проекта виртуальной реальности.
  • MSAA 8x включен
  • Запеченный свет включен
  • Создание и расположение световых зондов

Дополнительные задачи

В ходе оптимизации потребовались дополнительные задачи, чтобы ускорить процесс, а также исправить ошибку, связанную с использованием одного из пулов:

Ускорение в конфигурации

  • Создано контекстное меню для полуавтоматического назначения ссылок в «Редакторе-время», делая как можно более грязной сцену для принудительного сохранения соответствующих изменений.

  • Создан пункт меню редактора Unity для объединения всех дочерних мешей с использованием одного и того же материала, как это видно на изображении в предыдущем разделе «Пакетная обработка».

Исправить

  • Добавлено условие никогда не использовать повторно мяч из пула, если он в данный момент находится в руках игрока.

Вывод

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

Например, присваивание методам Awake/Start с помощью GetComponent или даже Find также допустимо в большинстве случаев, потому что это одноразовый вызов и он происходит в начале игры.

Кроме того, в большинстве случаев объекты пула также могут быть созданы в начале игры, а не во время редактирования.

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

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

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

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