Почему я должен всегда рассматривать создание и использование пулов объектов вместо создания нового объекта на лету?


25

Я читал об этом шаблоне несколько раз (с точки зрения передового опыта):

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

Тем не менее, я не знаю, что это на самом деле означает. Как я могу это реализовать?

Например, я могу создать экземпляр с GameObjectиспользованием Instantiateметода Unity?

Instantiate(prefab, new Vector3(2.0F, 0, 0), Quaternion.identity);

Это использование не рекомендуется? Что еще это может значить?



Благодаря Hellium, я не смотрел данное видео (слишком большое), но текст действительно помогает мне понять: «Процесс создания и уничтожения неэффективен и может замедлить ваши проекты»
— Мухаммад Файзан Хан

1
Обратите внимание, что хотя этот совет является общим, он не является абсолютным требованием для каждой игры. Особенно, если вы создаете небольшую / короткую настольную игру, отправку джема или прототип, вам не нужно изо всех сил внедрять пул. В моих тестах на замачивание Unity выдерживает даже массовые нересты и разрушения лучше, чем мы полагаем. ;) Но подумайте о создании пула, если вы делаете длинную игру, в которой вы не хотите, чтобы мусор накапливался и вызывал заикание, когда он собирался позже, или если вы нацелены на мобильные платформы, где любое влияние на производительность ощущается более остро.
— DMGregory

Спасибо @DMGregory Вы правы. Ваш вклад всегда ценный. Мы не должны беспокоиться о пуле объектов в небольших играх, так как это потребует дополнительной работы в кодировании.
— Мухаммед Файзан Хан

1
Это очень распространенный шаблон, но убедитесь, что он уравновешен с помощью правила: «Сначала профиль, а затем оптимизация». Легко оптимизировать вещи, которые не имеют значения.
— Cort Ammon - Восстановить Монику

Ответы:


41

Если вы планируете создавать множество экземпляров одного и того же префаба, вам определенно следует подумать об использовании пула объектов. Вызов функции Intytiate Unity - один из самых сложных методов вызова, которые вы можете сделать.

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

Например, в настоящее время я работаю над игрой с пулями в ад, которая требует, чтобы сотни пуль появлялись во время выполнения. Сначала я пытался сделать игру без пула объектов, но это закончилось катастрофой (менее 2 кадров в секунду). Теперь я собираю 500 пуль до начала игры, и игра работает на удивление быстро (200 кадров в секунду).

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

Учебник Себастьяна Лиги на YouTube - отличный ресурс для изучения пула объектов: https://youtu.be/LhqP3EghQ-Q


«Акт создания и уничтожения неэффективен и может замедлить ваши проекты». это причина? Таким образом, это означает, что мы должны кодировать немного больше (например, активировать деактивированный или снова установить позицию пули, чтобы мы могли снова стрелять)
— Мухаммед Файзан Хан

12
Возможно, стоит упомянуть распределение и сборку мусора в качестве основных источников затрат на повторное создание и уничтожение. Создайте достаточно мусора, и в конечном итоге вся игра должна ждать, пока сборщик мусора не сместит все это. ;)
— DMGregory

3
@corsiKa, это будет оптимизация эпохи 80-х. Unity может просто деактивировать рассматриваемые префабы, заставляя свои системы игнорировать его.
— congusbongus

2
«Например, если у вас есть игра, в которой ввод от игрока определяет, какой префаб создается, то у вас может не быть иного выбора, кроме как использовать обычный вызов Instantiate». - На самом деле, нет. Вы можете легко иметь несколько пулов объектов для разных префабов, выделенных для желаемых размеров при запуске (или загрузке сцены). Или, если кто-то хотел сделать это, пул объектов, который хранит несколько типов сборных, также может работать.
— Итан Бирляйн

1
@DMGregory В типичной среде GC перераспределение является большей частью затрат; в типичной среде без GC распределение - это большая часть затрат. Объединение объектов отлично подходит для обеих сторон, по большей части это просто две стороны одной медали. В крайнем случае, старые игры были написаны со всеми объектами, «выделенными» с самого начала - очень мало или вообще не было выделения / выделения памяти во время игры. Вы действительно не использовали ничего, что не было каким-то образом «объединено». Поскольку Unity использует много «метаданных» в реальном времени, объединение в пул может очень помочь - хотя это также может быть сложнее реализовать.
— Луан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.