Оптимизация игры на 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...
Глянул пару видосов твоих, очень перспективный Unity dev, подача со старта канала на очень высоком уровне, монтаж/звук/видео ряд. Не забрасывай ни в коем случае, слишком качественно.
Спасибо большое, не заброшу)
Божее мой, это то что я искал!! Здесь наконец то адекватный ответ, что такое наблюдатель в юнити, без интерфейсов и т.п.. Спасибо просто огромное!!!!!!!!!!!
P.s. я уже приметил зенжекты, визитер, и другие видео.. Погнал смотреть, и всем рекомендую, кто пытается разобраться в паттернах и т.п.!))
На здоровье)
Рекомендую ещё почитать про ключ "event"
Большое спасибо, не думал, что это есть в Юнити. Этот паттерн прям очень важный момент в Garry's Mod, именно он чаще всего используется там, реализуется через hook.
Тут ещё особенность, что в Lua, функция - это тип данных, и ты можешь его спокойно передавать и переназначать и так далее. И через hook (аналог event в шарпе) прописываются действия для каких-то функции, ну та же стрельба, в самой её функции OnAttackStarted и OnAttackStopped, и уже потом любой другой разработчик, может в эти хуки засовывать свои функции, какие пожелает. То есть:
1 - Не надо ломать те скрипты, где находится нужная тебе функция.
2 - Не надо искать, чтобы сломать те скрипты, где находится нужная тебе функция, ибо файлов может быть и 100 и 1000.
3 - Удобно и практично для масштабирования.
Ещё интересная практика обсервера, это разрешение на срабатывания исходного метода через Can. Допустим, CanAttack. Если он nil (не назначен) или true - всё норм, срабатывает. Если он false, значит исходный метод (Атака) не сработает.
Как всегда полезно. ЛУЧШИЙ 👍
Спасибо и от души душевно в душу)0)) 😋🔥
Спасибо, было интересно) и позновательно
Очень круто! За 7 минут настолько преисполнился... А ещё чуть с ума не сошёл, пока поймал "Тавтологичную тавтологию")))
Спасибо, стараюсь! 🤙
Это хорошо, что преисполнился 😎
Ля, ну хоть какой-то интерактив для тренировки реакции случайно получился
Мини игра на движке TH-cam с визуальным программированием 🤣
Понятный и очень полезный контент! Спасибо!
На здоровье)
Годнота, видно, что запарился со звуком и монтажем, подписка)
Спасибо)
Нет слов, просто отличный ролик!
Благодарю за тёплые слова!
Я где-то год назад наталкивался на ваши видео, очень понравились. Жаль что перестали выпускать. Но вот можно сделать видос рефакторинг для reuse equivalent principle - На 4:14 weaponaudio все равно осталась зависимость от weapon и weaponattack. Да Srp сделано, но было бы хорошо сделать этот компонент переиспользуемым. Где будет startaudio(weaponshot) , clipisempty, playsoundloop. Ну или применить isp и разделить на ещё более мелкие переиспользуемые компоненты. Конечно можно сказать что cohesion тогда будет маденьким для пакета weapon. Но все же можно было бы переиспользовать новые компоненты и создать новый пакет.
Да уже столько времени прошло с этого видео, мой стиль кода тоже сильно поменялся. Сейчас у меня есть просто универсальные AudioPlayer и AudioPool (не моно) как надстройки над AudioSource.
Почему перестал выпускать? Не перестал и прямо сейчас потихоньку новое видео монтирую)
@@NightTrainCode Мне показалось что последнее видео было полгода назад. Было бы интересно посмотреть видео про универсальные AudioPlayer и AudioPool
@@dimadancev714 Нет, 1-2 месяца назад последнее выкладывал)
AudioPlayer особо ничего интересного не хранит. А AudioPool - класс, в котором есть Capacity (количество AudioSource в пуле) и метод Play(AudioPreset preset, in Vector3 position) с различными перегрузками
AudioPreset - SO, в котором можно указать AudioClip, задать volume. Так же можно указать несколько клипов и включить параметр random. Своеобразный сахар
@@NightTrainCode Понял. Спасибо! Ну, буду ждать другое видео!
Топ контент....теперь то я точно знаю куда SR принцип не пойдет ;)
Благодарю)
Реально 🤣
Почему Action а не event Action? Если не делать event, то любой компонент сможет обнулить подписки вызвав OnSomething = null
Не знаю как новичкам, Но мне как програмисту (java/python) очень зашло. По вашим видео в очень сжатые сроки можно понять на что похоже программирование в Unity. Что по сути все программирование это работа с callback. Все сжато и класно.
Благодарю)
Единственное, в этом видео я не рассказал про ключ event, но про это есть в последнем
@@NightTrainCode Не все же сразу :). До этого думал что в Kotlin с groovy все послизывали, а оказывается с решетки: тот же безопасный вызов ?. и when as expression
Мне кажется , что удобней и понятней будет сделать событие смерти игрока, чем каждый раз проверять его здоровье если нужно выполнить какие-то действия после смерти юнита
Видос классный, молодец.
Так у нас и так есть событие смерти какого-то юнита (OnDeath), будь то игрок или враг 😉
И попытка его вызова происходит только при изменении здоровья (если оно
@@unreidunity2737 Благодарю)
Несите кислород, задыхаюсь от количества годноты за последнее время :3
Благодарю 😎🔥
Привет! Очень крутые видео! Но зачем это возводить в отдельный паттерн? Все и так используют ивенты. Типо если я использую ивенты, то я знаю про паттерн observer? )
А почему вы не пишете event перед Action?
Молодой был, глупый)
В новом видосе про это есть
@@NightTrainCode Можно ссылку на видос?)
@@BLITZBURY Самый новый на канале
Насчет держать переменную(ые) для того, чтобы проверить не подписан ли может быть лишним, чаще вижу что люди просто отписываются перед подпиской
Вариант интересный, но не лучшее решение
В идеале подписаться в старте и отписаться в OnDestroy, если есть возможность
Ruby Amanfu - Didn't
не понятно зачем ты подписываешься на изменение здоровья, обычно делают компоненты Нанесения урона или Восстановление хп и там делают подписку. Т.е. в каждом конкретном случае своя и она что то реализует. С неймингом не понятно OnHealthChanged - OnValueChanged, там у тебя класс UnitHealth - зачем дублировать Health
Тут мы именно методы в делегат засовываем? А в каком случае применяется слово event?
Да, методы, Action - это delegate void. Event тоже для событий юзается
Event не даёт вызывать делегат извне класса в котором он объявлен, и устанавливать значение извне через =, только через += или -=
@TheBigGangstaMouse А ещё подсвечивается в Rider'е по-другому и получает значок в виде молнии 😄
@@NightTrainCode В VS Code тоже, но это уже мелочь
привет, я хочу загрузить игру в assetstore. Я хочу, чтобы это выглядело как игра, в которой Unity выпускает свои игры, и после загрузки игра открывается мгновенно, скажите, пожалуйста, как это сделать. (использовал гугл-переводчик)
"Как игра, в которой Unity выпускает свои игры" - не могу понять)
@@NightTrainCode th-cam.com/video/SePwM2g_O3k/w-d-xo.html
Я утанул
4:45 В статике коллекции лучше не хранить, так еще Рихтер в "CLR via C#" писал - сборщик мусора потом часто не может собрать объекты, ктр туда пихали, и память течет. И еще вопрос, а почему используешь публичный Action, а не event Action ?