Доброго времени суток, дорогие читатели, большое спасибо за слова поддержки и полезные советы, который вы оставили в первой части Истории создания моей первой игры.
![](https://habrastorage.org/getpro/habr/upload_files/e6a/c23/9f6/e6ac239f61a423a6c4cd5592c9a3a2f4.gif)
Вопрос оптимизации стал актуальным, когда я попытался выложить игру в ЯИгры и не прошел модерацию, в частности из-за того, что игра зависала на Web платформе.
Изучив этот вопрос, я выделил несколько основных направлений, которые будут актуальны для моего проекта:
-
Графика:
Добавить спрайт в атлас
Сделать объекты статическими + выключать неиспользуемые
Перенос игры на одну сцену
-
Код:
Избавиться от Update
Добавить pool-objects
Кэшировать данные
Избавить от FindObjects
Оптимизировать звуковое сопровождение
Добавление мобильной версии
Перед началом работы я сделал скриншот окна статистики, чтобы понимать, в правильном ли направлении я двигаюсь.
![](https://habrastorage.org/getpro/habr/upload_files/8a4/bd4/030/8a4bd4030cd98efd3677bf7c7b5eb01f.png)
Процесс оптимизации
Атласы
В первую очередь, я решил добавить все спрайты в атласы, чтобы уменьшить количество вызовов отрисовки, и следовательно снизить Batching. Я начал было переносить все спрайты в фотошопе на одно полотно, но тут оказалось, что с версии Unity 2022 есть встроенная функция создания атласов, пришлось обновляться и доделывать уже в редакторе. Вот как изменились данные в окне Stats, после создания атласов:
![](https://habrastorage.org/getpro/habr/upload_files/f72/88f/b74/f7288fb74358ad0d7b2e21a15d92ad45.png)
Статические и выключенные объекты
Все объекты, которые неподвижно находятся на сцене, такие как кнопки меню, заголовки, подсказки, и название игры я сделал статическими. Когда они не задействованы в сцене, я просто их отключаю, и активирую при необходимости автоматически при помощи кода.
Перенос меню на сцену игры
Для минимизации задействования объектов, я решил реализовать всю игру в одной сцене. Для этого мне необходимо было объединить сцену меню и игры, переписать скрипты управления сценами и перенести все объекты меню на сцену игры.
При переносе объектов никаких проблем не возникло, но при объединении скриптов начался сущий кошмар. Зависимости скриптов друг от друга были повсюду, при изменении одного, ломалась вся цепочка взаимодействия и приходилось очень долго искать концы. Для наглядности я нарисовал общую схему взаимодействия скриптов в игре:
![Схема упрощена, в нее я не стал добавлять методы увеличения скорости на случайную величину, в случайный момент времени, случайное появление бомбы, и др. Схема упрощена, в нее я не стал добавлять методы увеличения скорости на случайную величину, в случайный момент времени, случайное появление бомбы, и др.](https://habrastorage.org/getpro/habr/upload_files/a1d/82a/e2e/a1d82ae2e0b7187cc13fbd4c826abe41.png)
В первоначальной версии игры объекты пейзажа и бомбы создавались методом Instantiate и при соприкосновении с мусоркой уничтожались, а их движением управлял класс MovenmentManager, при помощи метода FindObjectsOfType в Update, который находил все объекты со скриптом Object на сцене и двигал их в нужном направлении, с необходимой скоростью. Из многих источников я узнал, что эти операции достаточно ресурсоемкие, и спасет от этого всего меня лишь poolObject. что ж, попробуем..
Оптимизация кода
Чтобы использовать poolObject появилась необходимость менять всю структуру кода и игры. Главный игрок находился на месте, а объекты пейзажа двигались ему навстречу. Теперь же будет двигаться игрок, а объекты мира будут стоять неподвижно. Для этого я сделал трекер на камеру, который будет следить за изменением положения игрока по оси Х, и смещать камеру на такое же расстояние. Объекты на котором находятся управляющие скрипты и спавнеры я поместил в родительский объект, а именно - камеру. Разберемся с создаваемыми объектами по очереди
Облака
Я добавил на сцену 6 объектов (3 варианта по 2 экземпляра) в состоянии Active(false). Как только запускается игра Random выбирает любой из 6 объектов и активирует его, если он еще не активен. При активации облако движется с постоянной скоростью в локальной системе координат относительно своего спавнера (так создается впечатление параллакс эффекта). Через случайный промежуток времени, это действие повторяется. При соприкосновении с "мусоркой" за пределами видимой сцены, облако возвращается в точку спавнера и деактивируется, ожидая своей очереди.
![](https://habrastorage.org/getpro/habr/upload_files/766/964/00d/76696400d69ab50c34a05b6f04ca1d9d.png)
Бомбы и объекты игрового мира
С объектами игрового мира я решил сделать по другому. Я создал пул объектов, и добавил туда ScriptableObject с полем изображения (спрайта). Сделал массив из спрайтов, например, кактусов и при каждой генерации, достается один и тот же объект, в котором случайно выбирается спрайт из массива. Аналогично происходит и с другими.
Объекты которые выходя за зону видимости отключаются и возвращаются в пул, далее ждут своей очереди.
![](https://habrastorage.org/getpro/habr/upload_files/712/6ac/bff/7126acbff5b71d6969b0c54d9ec23c98.png)
Работа со звуками
Для управления звуками в игре, я сделал AudioMixer, в котором создал группы по назначениям: фоновая музыка, эффекты и звуки от UI.
![](https://habrastorage.org/getpro/habr/upload_files/08e/d44/4e6/08ed444e64260563c27cb6bb72a89471.png)
Ко всем звукам/музыке я применил необходимое форматирование. Для звуковых эффектов был выбран ADPCM, тк мы можем пожертвовать качеством звучания, а взамен получим хорошее сжатие. Для фоновой музыки я выбрал Vorbis, он сжимает звук, но качество теряется малозаметно. А тип загрузки Streaming, из за того что фоновая музыка играет постоянно на протяжении всей игры.
Добавил окошко управления звуками и распределил их по соответствующим группам, теперь при добавлении новой музыки или звуковых эффектов, необходимо будет указать только к какой группе они относятся, а все остальные настройки применятся автоматически.
![](https://habrastorage.org/getpro/habr/upload_files/c5a/e91/fb3/c5ae91fb3a1a2d842f8b7450228f327c.png)
Хочу поиграть на телефоне
Самым простым решением было сделать кнопку, которая будет появляться, если вы заходите в игру с мобильной платформы. А выглядит это так:
![](https://habrastorage.org/getpro/habr/upload_files/1fa/c52/e76/1fac52e76718185ccc65552652879cb8.jpg)
Подвожу итоги
![](https://habrastorage.org/getpro/habr/upload_files/c4f/873/b81/c4f873b8157bb1c32acb26dc3f72dd8e.png)
После всех манипуляций и ломания головы, как бы оптимизировать игру я пришел к тому что есть. По статистическим показателям существенных изменений в положительную сторону нет, скорее всего из за того, что игра маленькая и ресурсов затрачивает не так много. Из положительного, я узнал достаточно много нового и интересного, что надеюсь, пригодится в будущем.
Если кому то стало интересно, "пощупать игру" вы можете здесь. Буду благодарен обратной связи)
Планы на будущее
Хотелось бы добавить магазин со скинами и с возможностью менять локацию, буду изучать возможности этого вопроса.
Добавление дуэли с бандитом, при достижении определенного количества очков
Публикация на Яндекс Игры. Если кто то уже публиковался, окажите помощь) не получается сделать сохранение на облачном сервисе Яндекса, не могу пройти модерацию из за этого.
Спасибо за внимание и до следующей главы этой истории!
Комментарии (3)
RedBullet91
15.08.2024 08:03+1На задник можно было бы добавить пару домушек и красных гор чтобы фон синий не так бросался в глаза
Furyohfury
Почему на скрине итогов фпс в 2 раза меньше чем в начале?))
shai_hulud
Оптимизация это процесс достижения оптимальных параметров под задачу, если задача получить половину ФПС, то все успешно выполнено. КО