Оптимизация. Пул объектов (Objects Pool). Рассказываю на примерах в Unity3d

Поділитися
Вставка
  • Опубліковано 28 лют 2021
  • Поддержи канал, бро!
    paypal.me/gamedevlavka - мир
    boosty.to/gamedevlavka - рф
    И даже криптой (пока только Ethereum):
    0x7a53325D1C36Eea7BbE8C6a8D00f2a0efd580e77
    Урок по Unity, в котором я рассказываю про один из приемов оптимизации - пул объектов (Objects Pool). Прием, который позволяет сократить количество Instantiate для объектов с короткой продолжительностью "жизни". Что в последствии благоприятно влияет на производительность.
    Плюс, этот урок является отличным примером к предыдущему уроку о Generic классах в C#:
    • Generic классы в C#. Р...
    Подписуйся на канал в телеге, или на твиттер, там я публикую коротенькие типсы и практики, которые помогут писать код лучше, понятнее и эффективнее:
    Telegram: t.me/gamedevlavka
    Twitter: / gamedevlavka

КОМЕНТАРІ • 79

  • @PasterLak
    @PasterLak 3 роки тому +5

    Спасибо! Очень хороший и понятный пример пула объектов!

  • @tarastaras5595
    @tarastaras5595 2 роки тому +3

    Супер! Спасибо за труд!

  • @mizzzlo6536
    @mizzzlo6536 Рік тому +3

    Спасибо тебе и твоему ObjectPool. Вы мне очень помогли

  • @gen_nady
    @gen_nady 3 роки тому +6

    Делай дальше. Ролики отличные. Вечером попробую

  • @vladisslavss
    @vladisslavss 2 роки тому +2

    Хорошо показан пример. Отличный ролик.

  • @kitws
    @kitws 3 роки тому +2

    Спасибо! Очень понятно

  • @nomad4994
    @nomad4994 3 роки тому +8

    Привет!
    Комментарий поддержки)
    Очень интересные видео)
    Не останавливайся)

    • @gamedevlavka
      @gamedevlavka  3 роки тому +2

      Привет! Спасибо за поддержку)

  • @Fenix72rus
    @Fenix72rus 3 роки тому

    Спасибо за видео!

  • @user-rb8gi6yb3m
    @user-rb8gi6yb3m 3 роки тому +1

    Отлично, 😉 спасибо 👍

  • @user-ju9vc2us9b
    @user-ju9vc2us9b Рік тому +1

    То что нужно, спасибо

  • @mistertwink
    @mistertwink 5 місяців тому

    Начала писать свой пул с этого видео, потом пошла на другие, и в итоге все равно вернулась сюда, потому что здесь все намного понятнее. И есть хорошая возможность перестроить под себя то, что нужно, без излишних напряжений извилин)
    Спасибо большое! Это видео сильно упростило мне жизнь)

  • @antonpashkevich5061
    @antonpashkevich5061 2 роки тому +1

    Спасибо, наверное лучший Pool который я видел на UA-cam, и на Unity Learn.
    Сейчас по рандому смотрю твои видосики, хоч сказать что мне старые больше нравиться...
    В новых видосиков ты столько создаешь интерфейсов :c
    Шо просто путаешься, а здесь 1 скрипт и Pool готов!

  • @zhizhikkkk3796
    @zhizhikkkk3796 Рік тому +1

    пасиб большое

  • @user-mo4fb1tr6c
    @user-mo4fb1tr6c 3 роки тому

    Спасибо!

  • @user-ml5tn8qn8j
    @user-ml5tn8qn8j Рік тому +2

    Отличный вариант, чтобы делать снаряды выстрелов и другие эффекты

  • @neverworld8815
    @neverworld8815 2 роки тому +5

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

  • @grayhouse6925
    @grayhouse6925 2 роки тому +1

    Видео классное. Одно замечание важное для следующих видео: null - это не ноль;

  • @kat.shnaider
    @kat.shnaider Рік тому +2

    очень полезные видео у тебя и понятно объясняешь, спасибо большое! подписка и лайк однозначно!
    было бы здорово, если бы ты снял видео о паттерне фабрика)

    • @gamedevlavka
      @gamedevlavka  Рік тому +1

      Да, надо заняться и этой темой)

    • @kat.shnaider
      @kat.shnaider Рік тому

      @@gamedevlavka спасибо 🤗

  • @alexixrugis
    @alexixrugis 3 роки тому +4

    Это просто великолепно!
    Почему здесь так мало подписчиков?

    • @gamedevlavka
      @gamedevlavka  3 роки тому +3

      Потому что канал еще молодой. Но ты можешь помочь ему, поделившись роликом в соц. сетях :)

  • @yaskadef
    @yaskadef 4 місяці тому +1

    хз как сломать эту кнопку лайка

  • @sutr4531
    @sutr4531 Місяць тому +1

    пул хороший, но медленный - O(n). потому как каждый раз в цикле ищет свободный элемент. если ввести индекс на текущую позицию в пуле, то отпадёт необходимость в цикле. и сложность алгоритма будет уже O(1). а это уже значительно веселее, т.к. скорость работы пула уже не будет зависеть от количества данных в нём.

    • @gamedevlavka
      @gamedevlavka  Місяць тому

      @@sutr4531 отличное предложение

  • @tadwhat
    @tadwhat Рік тому

    Классные видео! Удачный выбор ли в пользу массива типа List? Он имеет capacity и выделяет под него достаточно памяти, при большом количестве обьектов рациональнее, использовать Stack - при большем количестве и вытягивать от туда , ну или Linked List , но при обращении по индексу, сложность - линейная , но тут это не используется, Object Pull сам выпрашивает фабрику - это как бы входная точка для создания и вытягивания фабрик😀

  • @ArIsm-rg7tw
    @ArIsm-rg7tw 3 роки тому +1

    👍👍👍

  • @nightyonetwothree
    @nightyonetwothree 2 роки тому +5

    думаю включать элемент в HasElement() не очень логично, т.к. исходя из названия метода мы ожидаем получить ссылку на объект/либо нуль, а вовсе не проихводить с ним какие то действия (включение). Логичнее включать его в GetElement(), где уже логика подразумевает доставание/создание объекта и его активацию (в случае создания - флагом).

    • @gamedevlavka
      @gamedevlavka  2 роки тому +6

      Полностью согласен, так не надо делать!

  • @user-ro8yn4kn7f
    @user-ro8yn4kn7f Рік тому

    Отличные видео, спасибо! Но вопрос, зачем ты используешь " this" там где это не обязательно? привычка?

  • @tarastaras5595
    @tarastaras5595 2 роки тому +2

    Супер! Спасибо за труд!
    Вопрос. В методе CreateCube сначала создается обьект на сцене, а потом меняется его позиция, верно?

    • @gamedevlavka
      @gamedevlavka  2 роки тому +2

      Объект не создаётся, он включается. Создаётся он при создании пула, то есть в старте. Да, он включается на сцене и затем меняется его позиция

  • @user-kw4re1nr2r
    @user-kw4re1nr2r Рік тому

    Что делать, если скрипт (L10 Pool Example) отказывается принимать префаб?

  • @lakostyali2583
    @lakostyali2583 Рік тому

    Привет , для чего мы создали 2 конструктора PoolMono?

  • @yaroslav5933
    @yaroslav5933 9 місяців тому +1

    Чет я не понимаю, зачем использовать generic class в юнити, ведь все объекты на сцене имеют 1 тип GameObject.

  • @Sv9zlsT
    @Sv9zlsT 3 роки тому +1

    привет, хорошее видео, но есть пару вопросов по СОЛИДности метода HasFreeElement он всё таки выглядит печально, так как имеет больше одной ответствнности, лучше его разделить, и out нас полностью обязывает использовать этот функционал

    • @gamedevlavka
      @gamedevlavka  3 роки тому +4

      Привет! СОЛИДность в плане единой ответственности предназначается для классов, а не для методов. Да, соглашусь, что принцип нужно соблюдать и в методах, по-хорошему. Но бывает, что метод выполняет не одно действие, и HasFreeElement() не единственный такой случай. В таких случаях мы либо делаем соответствующее название метода (чтобы было понятно, что делается внутри), либо, как в моем случае, мы можем использовать обязательный вывод наружу через out. Таким образом, если элемент есть он сразу попадает к нам в руки.
      Таким же способом устроен например Physics.Raycast() - внутренний метод Unity, где через out выводятся данные о попадании рейкаста, если таковое имеется.

  • @crazist3325
    @crazist3325 2 роки тому

    Видео очень хорошее, для уровня уже выше начинающего, но вот вопрос что делать если разный префа и в разное время, стоит создать просто 2ва пула или уже в самом пуле менять

    • @neverworld8815
      @neverworld8815 2 роки тому

      Построить иерархию, и управлять ей, например есть главный объект пул, внутри 4 объекта (4 типа), и в каждом типе группа своих объектов, через главный пул можно манипулировать всеми ветками по первому принципу Solid, если кроме как по типу, будут другие сортировщики, то тогда всё-ровно нету смысла создавать доп классы, достаточно сделать грамотный поиск внутри пула

  • @tuz3682
    @tuz3682 Рік тому +2

    Классный ролик! По Вашим видео изучаю Unity и C#. Имя пользователя - это Ваша мечта?)

  • @user-dw4rw4ph2o
    @user-dw4rw4ph2o 2 роки тому

    Спасибо за видео, очень хорошая подача и материал, но подскажи пожалуйста: Почему prefab типа L10Cube, и когда в инспекторе вы его перетягиваете в Тестер - он тоже забирает только элемент L10Cube, но пул спавнит его вместе с 3D телом куба, как префаб ведь указан только скрипт

    • @serhiipodoliak9212
      @serhiipodoliak9212 2 роки тому

      Привет, если нашел ответ на свой вопрос, скинь пожалуйста ссылку на ответ, или в каком направлении копать

    • @tomasgammister5776
      @tomasgammister5776 Рік тому

      А как ты заспавнишь один скрипт без объекта ? ))) это просто ссылка на объект с компонентом L10Cube. не было бы этого скрипта, не перетянул бы

    • @exregisterqq
      @exregisterqq Рік тому

      @@Toki- внутри этого скрипта есть методы, которые управляют кубом, в конце показал он

  • @Evgeniy_LuxorGame
    @Evgeniy_LuxorGame 3 роки тому +4

    С таким пулом могут быть проблемы.. например, я использую этот пул для пуль/ракет или т.п.
    Снаряд, при попадании в коллайдер игрока должен отключиться и нанести урон.
    Вот в чем ошибка: если игрок не двигается, то снаряд, который ранее в него попал и отключился снова берётся из пула и активируется там же, где все ещё стоит игрок. И событие OnTrigerEnter срабатывает ДО того как мы переместили снаряд в нужное место. Потому что он активируется сразу как берётся из пула, а перемещается в нужное место после активации

    • @gamedevlavka
      @gamedevlavka  3 роки тому +2

      Хорошее замечание. Для такого случая можно дописать в пул дополнительный метод GetFreeElement с параметром Position. То есть по сути расширить его поведение для ваших целей.

    • @IgorKu-m4o
      @IgorKu-m4o 2 роки тому

      Пул используют только для слабых телефонов? Для ПК не обязательно?

    • @gamedevlavka
      @gamedevlavka  2 роки тому +4

      @@IgorKu-m4o их использование рекомендуется везде. Лаг может происходить и на ПК, он просто меньше будет.

    • @neverworld8815
      @neverworld8815 2 роки тому

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

  • @user-ro8yn4kn7f
    @user-ro8yn4kn7f Рік тому

    Все круто и понятно, одно не понял, как происходит, что в проверке на 59 сточке , при вызове метода HasFree, возвращается елемент , тогда как он возващает bool. Просто не могу врубиться, если не трудно может кто то обьяснит в кратце

    • @user-ro8yn4kn7f
      @user-ro8yn4kn7f Рік тому

      Все догнал) , коммент для продвижения)

  • @user-lk1lh7pc5l
    @user-lk1lh7pc5l Рік тому +1

    касательно кубика, кто новичок, вместо корутин, установите себе unitask библиотеку
    это гораздо удобнее, смотрите как у меня это выглядит, поверьте, вы везде будете это юзать
    это в библиотеки
    using UnityEngine;
    using System;
    using Cysharp.Threading.Tasks;
    это в ваш класс
    [SerializeField] private float _lifetime;
    void OnEnable() { Destroy(); }
    async void Destroy()
    {
    await UniTask.Delay(TimeSpan.FromSeconds(_lifetime));
    this.Deactivate();
    }
    public void Deactivate()
    {
    this.gameObject.SetActive(false);
    }

  • @MesokiDante
    @MesokiDante 2 роки тому

    Здравствуйте, я новичок в Unity3D поэтому хотел бы узнать как сделать так чтобы добавлять не один объект а несколько объектов и вызывать их рандомна, спасибо за раннее за ответ.

    • @dmytromahas9207
      @dmytromahas9207 2 роки тому

      Привет, если ты новенький в юнити то лучше не спеши с такими темами, это более продвинутый левел, только зря время потратишь.

  • @Noulderleito
    @Noulderleito 6 місяців тому +1

    Интересно мы после смерти обратно в пул попадаем или в сборщик мусора

  • @PS-vj6jz
    @PS-vj6jz 2 роки тому

    Хороший ролик, но это пул через list, есть ли более быстрые реализации (драсти оптимизация)). Я как-то натыкался на pool через queue.

    • @gamedevlavka
      @gamedevlavka  2 роки тому +1

      Есть загвоздка, ты не можешь пробежаться по Queue, чтобы найти неактивный элемент. Поэтому очередь не совсем подходит под большинство задач, связанных с пулом)

    • @PS-vj6jz
      @PS-vj6jz 2 роки тому

      @@gamedevlavka а есть вообще варианты кроме списков?

    • @gamedevlavka
      @gamedevlavka  2 роки тому +1

      @@PS-vj6jz список самый оптимальный, он быстрый, он динамический, и его достаточно. Лучше не получится, с тем функционалом, что представлен в видео

    • @PS-vj6jz
      @PS-vj6jz 2 роки тому +1

      @@gamedevlavka окей.

    • @neverworld8815
      @neverworld8815 2 роки тому +1

      @@PS-vj6jz List это по сути копирование массива в новый, и "удаление" предыдущего, максимально оптимально это использовать 1 массив за всю жизнь который выделит фиксированное количество памяти, а для этого надо с 100% уверенностью установить лимиты по количеству объектов

  • @goga19980
    @goga19980 3 роки тому +1

    Для чего/Почему везде пишешь this - где это необязательно?)

    • @gamedevlavka
      @gamedevlavka  3 роки тому +1

      Ответ на этот вопрос здесь => t.me/gamedevlavka/15

    • @leningradetsfromshusharsta985
      @leningradetsfromshusharsta985 3 роки тому

      @@gamedevlavka но ведь для того чтобы отличать поля от локальных переменных, придумали называть поля с _, и вместо this.feild писать _feild и так и так понятно, что речь идёт о поле, а не переменной, но с подчеркиванием быстрее, и меньше раздуваются строки

    • @gamedevlavka
      @gamedevlavka  3 роки тому

      @@leningradetsfromshusharsta985 это касается не только полей, но и методов. Вообще это индивидуальный подход, я ничего не имею против _ в общей практике.
      Это больше для себя. Мне так читать удобнее, и пишу я this быстрее, чем ставлю _.

  • @dmytromahas9207
    @dmytromahas9207 2 роки тому

    Зачем создавать 2 конструктора для PoolMono если можно по дефолту для контейнера поставить значение null?
    public PoolMono(T prefab, int count, Transform container = null) {
    this.container = container;
    }

    • @neverworld8815
      @neverworld8815 2 роки тому

      Потому что он может быть не null, но если не указан то будет null

    • @dmytromahas9207
      @dmytromahas9207 2 роки тому

      @@neverworld8815 ну если укажешь то уже не будет null, в противном по дефолту подставится null

    • @neverworld8815
      @neverworld8815 2 роки тому

      @@dmytromahas9207 я то-же самое сказал, только короче

    • @dmytromahas9207
      @dmytromahas9207 2 роки тому

      @@neverworld8815 ахахах, так зачем 2 конструктора ??

    • @neverworld8815
      @neverworld8815 2 роки тому

      @@dmytromahas9207 я уже ответил

  • @user-hp2cg6px8c
    @user-hp2cg6px8c 3 роки тому +1

    а зачем два конструктора
    охерел, что так вообще бывает
    у нас, у HTML-программистов, все не так

  • @IgorKu-m4o
    @IgorKu-m4o 2 роки тому +2

    Почему свойства именуются с маленькой буквы? Свойства принято именовать с большой, а поля с маленькой.
    В типовом коде Юнити тоже с маленькой 🤔

    • @gamedevlavka
      @gamedevlavka  2 роки тому +1

      Есть разные конвенции и стили написания кода. То, что Майкрософт так рекомендует - не значит, что это удобно всему миру. Юнити решили, что будут использовать camelCase для публичных полей и свойств, а я решил, что не хочу, чтобы мой стиль отличается от стиля юнити. Такие дела)

    • @neverworld8815
      @neverworld8815 2 роки тому

      Это по сути косметика, в некоторых командах разработчиков могут быть свои собственные знаки или ключевые слова для удобства