Оптимизация игры на Unity. Паттерн Observer

แชร์
ฝัง
  • เผยแพร่เมื่อ 13 ก.ค. 2024
  • Не нужно каждый раз проверять состояние объекта в Update, когда есть способ проверки только при изменении значения! Как реализовать Паттерн «Наблюдатель» (Observer) в Unity, C#? Об этом в ролике 🔥
    • Примеры из реального проекта на Unity. Также затронем работу со свойствами (аксесорами get и set) в C# и делегаты и события
    • Разрываем жёсткие зависимости в коде! Паттерн наблюдатель в Unity с примерами
    Оптимизация вашего кода C#
    Салют, ты на канале Night Train Code 😎
    Этот вариант оптимизации игры на Unity3D подойдёт и под мобильные устройства. Исправляем низкий фпс
    • 🖤 GitHub: github.com/MeeXaSiK
    • 🖤 VK: nighttraincode
    • 🖤 Telegram: t.me/nighttraincode
    • 🖤 Instagram: / the.meps_
    Таймлайн:
    00:00 ► Вступление
    00:19 ► Паттерн наблюдатель C#.
    00:32 ► Проблема постоянной проверки в Update
    00:53 ► Для чего нужен паттерн Observer в C#?
    01:24 ► Паттерн Observer на практике в Unity
    01:48 ► Как быстро объявить делегат в C#?
    03:13 ► Разрываем жёсткие зависимости
    04:28 ► Отписка от события при его вызове
    05:13 ► Аккуратнее с подписками на события
    05:23 ► Избавляемся от проверок в Update. Аргументы для события. Автоматические свойства в C#.
    06:40 ► Паттерн Observer + Полиморфизм
    07:04 ► Спасибо за просмотр :)
    Можешь подписаться на канал, чтобы не пропустить новые ролики по оптимизации игр и их разработке 🤙
    Поддержка канала:
    www.donationalerts.com/r/nigh...

ความคิดเห็น • 52

  • @DominusFuror
    @DominusFuror ปีที่แล้ว +11

    Глянул пару видосов твоих, очень перспективный Unity dev, подача со старта канала на очень высоком уровне, монтаж/звук/видео ряд. Не забрасывай ни в коем случае, слишком качественно.

    • @NightTrainCode
      @NightTrainCode  ปีที่แล้ว +2

      Спасибо большое, не заброшу)

  • @parrotgames44
    @parrotgames44 2 ปีที่แล้ว +8

    Божее мой, это то что я искал!! Здесь наконец то адекватный ответ, что такое наблюдатель в юнити, без интерфейсов и т.п.. Спасибо просто огромное!!!!!!!!!!!
    P.s. я уже приметил зенжекты, визитер, и другие видео.. Погнал смотреть, и всем рекомендую, кто пытается разобраться в паттернах и т.п.!))

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +3

      На здоровье)
      Рекомендую ещё почитать про ключ "event"

  • @titanovsky
    @titanovsky 9 หลายเดือนก่อน +2

    Большое спасибо, не думал, что это есть в Юнити. Этот паттерн прям очень важный момент в Garry's Mod, именно он чаще всего используется там, реализуется через hook.
    Тут ещё особенность, что в Lua, функция - это тип данных, и ты можешь его спокойно передавать и переназначать и так далее. И через hook (аналог event в шарпе) прописываются действия для каких-то функции, ну та же стрельба, в самой её функции OnAttackStarted и OnAttackStopped, и уже потом любой другой разработчик, может в эти хуки засовывать свои функции, какие пожелает. То есть:
    1 - Не надо ломать те скрипты, где находится нужная тебе функция.
    2 - Не надо искать, чтобы сломать те скрипты, где находится нужная тебе функция, ибо файлов может быть и 100 и 1000.
    3 - Удобно и практично для масштабирования.
    Ещё интересная практика обсервера, это разрешение на срабатывания исходного метода через Can. Допустим, CanAttack. Если он nil (не назначен) или true - всё норм, срабатывает. Если он false, значит исходный метод (Атака) не сработает.

  • @NeGaT1V1
    @NeGaT1V1 2 ปีที่แล้ว +4

    Как всегда полезно. ЛУЧШИЙ 👍

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +1

      Спасибо и от души душевно в душу)0)) 😋🔥

  • @antonpashkevich5061
    @antonpashkevich5061 ปีที่แล้ว +1

    Спасибо, было интересно) и позновательно

  • @vladislavyurevich2247
    @vladislavyurevich2247 2 ปีที่แล้ว +2

    Очень круто! За 7 минут настолько преисполнился... А ещё чуть с ума не сошёл, пока поймал "Тавтологичную тавтологию")))

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว

      Спасибо, стараюсь! 🤙
      Это хорошо, что преисполнился 😎
      Ля, ну хоть какой-то интерактив для тренировки реакции случайно получился
      Мини игра на движке TH-cam с визуальным программированием 🤣

  • @user-dv5ue1om3m
    @user-dv5ue1om3m 2 ปีที่แล้ว +1

    Понятный и очень полезный контент! Спасибо!

  • @it_thoughts
    @it_thoughts ปีที่แล้ว +1

    Годнота, видно, что запарился со звуком и монтажем, подписка)

  • @nuciesto6917
    @nuciesto6917 2 ปีที่แล้ว +2

    Нет слов, просто отличный ролик!

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +1

      Благодарю за тёплые слова!

  • @dimadancev714
    @dimadancev714 ปีที่แล้ว +1

    Я где-то год назад наталкивался на ваши видео, очень понравились. Жаль что перестали выпускать. Но вот можно сделать видос рефакторинг для reuse equivalent principle - На 4:14 weaponaudio все равно осталась зависимость от weapon и weaponattack. Да Srp сделано, но было бы хорошо сделать этот компонент переиспользуемым. Где будет startaudio(weaponshot) , clipisempty, playsoundloop. Ну или применить isp и разделить на ещё более мелкие переиспользуемые компоненты. Конечно можно сказать что cohesion тогда будет маденьким для пакета weapon. Но все же можно было бы переиспользовать новые компоненты и создать новый пакет.

    • @NightTrainCode
      @NightTrainCode  ปีที่แล้ว +2

      Да уже столько времени прошло с этого видео, мой стиль кода тоже сильно поменялся. Сейчас у меня есть просто универсальные AudioPlayer и AudioPool (не моно) как надстройки над AudioSource.
      Почему перестал выпускать? Не перестал и прямо сейчас потихоньку новое видео монтирую)

    • @dimadancev714
      @dimadancev714 ปีที่แล้ว

      @@NightTrainCode Мне показалось что последнее видео было полгода назад. Было бы интересно посмотреть видео про универсальные AudioPlayer и AudioPool

    • @NightTrainCode
      @NightTrainCode  ปีที่แล้ว +1

      @@dimadancev714 Нет, 1-2 месяца назад последнее выкладывал)
      AudioPlayer особо ничего интересного не хранит. А AudioPool - класс, в котором есть Capacity (количество AudioSource в пуле) и метод Play(AudioPreset preset, in Vector3 position) с различными перегрузками
      AudioPreset - SO, в котором можно указать AudioClip, задать volume. Так же можно указать несколько клипов и включить параметр random. Своеобразный сахар

    • @dimadancev714
      @dimadancev714 ปีที่แล้ว +1

      @@NightTrainCode Понял. Спасибо! Ну, буду ждать другое видео!

  • @vacsa
    @vacsa 2 ปีที่แล้ว +1

    Топ контент....теперь то я точно знаю куда SR принцип не пойдет ;)

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +1

      Благодарю)
      Реально 🤣

  • @shtolyan
    @shtolyan ปีที่แล้ว +2

    Почему Action а не event Action? Если не делать event, то любой компонент сможет обнулить подписки вызвав OnSomething = null

  • @yuriisolopov9113
    @yuriisolopov9113 2 ปีที่แล้ว +2

    Не знаю как новичкам, Но мне как програмисту (java/python) очень зашло. По вашим видео в очень сжатые сроки можно понять на что похоже программирование в Unity. Что по сути все программирование это работа с callback. Все сжато и класно.

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +1

      Благодарю)
      Единственное, в этом видео я не рассказал про ключ event, но про это есть в последнем

    • @yuriisolopov9113
      @yuriisolopov9113 2 ปีที่แล้ว +1

      @@NightTrainCode Не все же сразу :). До этого думал что в Kotlin с groovy все послизывали, а оказывается с решетки: тот же безопасный вызов ?. и when as expression

  • @unreidunity2737
    @unreidunity2737 2 ปีที่แล้ว +2

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

    • @unreidunity2737
      @unreidunity2737 2 ปีที่แล้ว

      Видос классный, молодец.

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +1

      Так у нас и так есть событие смерти какого-то юнита (OnDeath), будь то игрок или враг 😉
      И попытка его вызова происходит только при изменении здоровья (если оно

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว

      @@unreidunity2737 Благодарю)

  • @VitVit312
    @VitVit312 2 ปีที่แล้ว +2

    Несите кислород, задыхаюсь от количества годноты за последнее время :3

  • @great8814
    @great8814 2 ปีที่แล้ว +1

    Привет! Очень крутые видео! Но зачем это возводить в отдельный паттерн? Все и так используют ивенты. Типо если я использую ивенты, то я знаю про паттерн observer? )

  • @StratoCatster
    @StratoCatster 2 ปีที่แล้ว +4

    А почему вы не пишете event перед Action?

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +3

      Молодой был, глупый)
      В новом видосе про это есть

    • @BLITZBURY
      @BLITZBURY ปีที่แล้ว

      @@NightTrainCode Можно ссылку на видос?)

    • @NightTrainCode
      @NightTrainCode  ปีที่แล้ว

      @@BLITZBURY Самый новый на канале

  • @N1kkyS
    @N1kkyS 2 ปีที่แล้ว +1

    Насчет держать переменную(ые) для того, чтобы проверить не подписан ли может быть лишним, чаще вижу что люди просто отписываются перед подпиской

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว +1

      Вариант интересный, но не лучшее решение
      В идеале подписаться в старте и отписаться в OnDestroy, если есть возможность

  • @GGamess
    @GGamess ปีที่แล้ว

    Ruby Amanfu - Didn't

  • @GGamess
    @GGamess ปีที่แล้ว +2

    не понятно зачем ты подписываешься на изменение здоровья, обычно делают компоненты Нанесения урона или Восстановление хп и там делают подписку. Т.е. в каждом конкретном случае своя и она что то реализует. С неймингом не понятно OnHealthChanged - OnValueChanged, там у тебя класс UnitHealth - зачем дублировать Health

  • @user-yb2xf7lc1n
    @user-yb2xf7lc1n 2 ปีที่แล้ว +1

    Тут мы именно методы в делегат засовываем? А в каком случае применяется слово event?

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว

      Да, методы, Action - это delegate void. Event тоже для событий юзается

    • @thebiggangstamouse1530
      @thebiggangstamouse1530 2 ปีที่แล้ว +1

      Event не даёт вызывать делегат извне класса в котором он объявлен, и устанавливать значение извне через =, только через += или -=

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว

      @TheBigGangstaMouse А ещё подсвечивается в Rider'е по-другому и получает значок в виде молнии 😄

    • @thebiggangstamouse1530
      @thebiggangstamouse1530 2 ปีที่แล้ว

      @@NightTrainCode В VS Code тоже, но это уже мелочь

  • @gamingpro3324
    @gamingpro3324 2 ปีที่แล้ว

    привет, я хочу загрузить игру в assetstore. Я хочу, чтобы это выглядело как игра, в которой Unity выпускает свои игры, и после загрузки игра открывается мгновенно, скажите, пожалуйста, как это сделать. (использовал гугл-переводчик)

    • @NightTrainCode
      @NightTrainCode  2 ปีที่แล้ว

      "Как игра, в которой Unity выпускает свои игры" - не могу понять)

    • @gamingpro3324
      @gamingpro3324 2 ปีที่แล้ว

      @@NightTrainCode th-cam.com/video/SePwM2g_O3k/w-d-xo.html

  • @crazist3325
    @crazist3325 2 ปีที่แล้ว

    Я утанул

  • @La89095168648
    @La89095168648 ปีที่แล้ว

    4:45 В статике коллекции лучше не хранить, так еще Рихтер в "CLR via C#" писал - сборщик мусора потом часто не может собрать объекты, ктр туда пихали, и память течет. И еще вопрос, а почему используешь публичный Action, а не event Action ?