38

[Туториал] Простой и удобный пул объектов для Unity3D

Урок рассчитан на новичков, у профи я догадываюсь уже написаны свои супер пулы на все случаи жизни =)


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

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

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

Вот так выглядит сборщик мусора в мобильной стрелялке без пулов:

Так чем же нам поможет пул?
Очень просто - вместо уничтожения, объекты будут только деактивироваться, и записываться в пул, оставаясь таким образом в оперативной памяти. А вместо создания новых объектов, будут браться уже созданные объекты из пула, и только активироваться!

Дальше опишу свою реализацию пула на юнити, универсальную и простую в использовании:

Для начала инициализация:

Метод PoolManager.init() надо будет дёрнуть в начале игры, передав в параметр трансформ того геймобжекта, который точно не будет уничтожаться. В этот геймобжект будут класться все деактивированные объекты, чтобы случайно не удалить их по ходу игры, вызвав Destroy() изначального родительского геймобжекта =)

Про словарь (Dictionary) будет дальше.

Функция получения объекта из пула:

В параметр PoolManager.getGameObjectFromPool() надо передать префаб, по которому создаётся объект.

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

Строчка if(!poolsDictionary.ContainsKey(prefab.name)) проверяет, был ли уже в пуле объект от этого префаба, и если нет, то далее создаётся хранилище (LinkedList) для объектов которые создаются по этому префабу.


Строчка  if (poolsDictionary[prefab.name].Count > 0) проверяет, есть ли сейчас в хранилище деактивированные объекты от этого префаба. Если да, то объект берётся из хранилища, делается активным (SetActive()) и возвращается как результат работы функции.

Если же хранилище пустует, то создаётся новый объект через GameObject.Instantiate().
Ему присваивается имя, префаба, которое потом будет использоваться для возвращения в пул, и функция возвращает новый объект.

Функция возврата объекта в пул:

Тут всё просто, берётся имя объекта который мы хотим вернуть в пул, по этому имени в словаре находится хранилище, объект добавляется туда, переносится в безопасный parent и деактивируется.

Всё, пул готов!

Реализация очень простая, но у неё есть пара ограничений:
1) Нельзя делать префабы с одинаковыми названиями, лежащие в разных папках. В этом пуле они перемешаются потому что тут всё играется от названия префаба.
2) И соответственно нельзя динамически менять имя пулируемого геймобжекта, потому что оно должно быть как у префаба.

Но благодаря этим небольшим ограничениям, не надо возиться со всякими дополнительными компонентами типа IPoolable и т.д., мой пул очень прост в использовании. Просто вместо GameObject.Instantiate(prefab) вызываешь PoolManager.getFromPool(prefab), А вместо GameObject.Destroy(gameObject) PoolManager.putToPool(gameObject)

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

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества