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


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.