Version: 2021.1
Графические приёмы
Оптимизации рендеринга

Приёмы в коде и игровом процессе

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

Исторический пример

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

Создатели игры Space Invaders имели в своём распоряжении небольшое количество RAM, так что им приходилось следить за потреблением памяти. Если бы они позволяли игроку стрелять раз в секунду и предлагали бы бонус, сокращающий время перезарядки до половины секунды, им пришлось бы постоянно проверять - хватает ли памяти для всех выпущенных пуль, если игрок стреляет так часто, как только может и при этом все выпущенные пули “живут” как можно дольше не по падая по препятствиям. Вероятно это создало бы для них проблему, так что они просто выделяют память для одной пули и только её и используют. Как только пуля “умирает”, она просто деактивируется, перемещается на новое место и заново активируется при очередном выстреле. При этом пуля занимает одно и то же место в памяти и ей не приходится его менять, и её постоянно не удаляют и не создают заново.

Оптимизация или жемчужина игрового процесса?

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

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

Будет ли X быстро работать на мобильных устройствах?

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

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

Просто и гибко, но медленно

  • Твёрдые тела ограничены 2мя измерениями в 2D игре.
  • Твёрдые тела на пулях.
  • Частое использование Instantiate и Destroy.
  • Множество отдельных 3D объектов для собираемых предметов или персонажей.
  • Расчёты каждый кадр.
  • Использование OnGUI для вашего GUI или HUD.

Сложно и с ограничениями, но быстро

  • Написание собственной физики для 2D игры.
  • Самостоятельное определение столкновений для пуль.
  • Использование пула объектов вместо Instantiate и Destroy.
  • Использование анимированных спрайтов у частиц для представления простых объектов.
  • Проведение ресурсоёмких вычислений раз в несколько кадров и кэширование результатов.
  • Своё решение для GUI.

Примеры

Сотни вращающихся собираемых монет с динамическим освещением на экране в один момент времени

  • НЕТ: Каждая монета - отдельный объект с твёрдым телом и скриптом, который его вращает и позволяет его подобрать.
  • ДА: Монеты - это система частиц с анимированной текстурой, один скрипт проверяет на столкновение все монеты и устанавливает их цвет в зависимости от расстояния до источника освещения.
    • This example is implemented in the Scripting Optimization page.

Своя пользовательская симуляция мягких тел

  • НЕТ: В игровом мире повсюду лежат подушки, которые вы можете бросать как угодно и скидывать их в отдельные груды.
  • ДА: Ваш персонаж - подушка, он в игре только один и ситуации, в которых он окажется в некотором роде предсказуемы (он сталкивается только со сферами и ориентированными по осям кубами). Возможно, вы сможете запрограммировать что-то, что не будет полностью имитировать симуляцию физики мягких тел, но будет выглядеть достаточно хорошо и при этом быстро работать.

30 вражеских персонажей, одновременно стреляющих по игроку

  • НЕТ: У каждого врага должен быть свой skinned меш, отдельный объект для его оружия, и оно создаёт экземпляр пули с твёрдым телом при каждом выстреле. Каждый враг учитывает состояние всех его соотечественников в сложном скрипте ИИ, который выполняется каждый кадр.
  • ДА: Большинство врагов находятся далеко и представлены отдельными спрайтами, либо враги двухмерные и в любом случае представляют из себя просто группу спрайтов. Каждая пуля врага отрисовывается в той же системе частиц и симулируется скриптом, который просчитывает только элементарную физику. Каждый враг обновляет состояние своего ИИ дважды в секунду, в соответствии с состоянием других врагов в его секторе.

Как и почему оптимизируют скрипты

Читайте на странице Оптимизация скриптов.

Графические приёмы
Оптимизации рендеринга