Паттерн State, паттерн состояние, Unity C#

  Рет қаралды 3,760

Sergey Kazantsev

5 ай бұрын

Новый видосик по паттерну State
Ссылка на гитхаб на проект
github.com/Haywaar/ShawarmaFight - проект с шаурмой
github.com/Haywaar/PatternDemoStorage - пример с башнями
Лежит по пути Assets/Patterns/State/GoodExample
Автору на кофе и шаурму
4276 5500 5792 8742 - карта Сбербанка
Если будут вопросы
мой тг @wargy
моя почта kazancev.s215@gmail.com
Тайминги:
00:00 Введение
00:26 Определение
01:08 Пример из жизни
02:40 UML-схема
04:05 Паттерн State и конечные автоматы
05:09 Практический пример, башни TD - введение
06:02 Практический пример - плохое решение через switch-case
07:28 Практический пример - хорошее решение через State
08:45 Где использовать паттерн State в геймдеве?
09:38 Паттерн State в проекте ShawarmaFight
11:05 State vs Strategy
12:55 Финал

Пікірлер: 52
@igor_mutny
@igor_mutny 5 ай бұрын
Каждое видео автора смотрю с широко раскрытыми глазами и ушами 😁 В плане объяснения архитектурных приемов автор - просто лучший! Нигде не видел, чтобы кто-то мог объяснять подобные темы настолько просто и наглядно. Я уже не один раз применял знания, полученные с этого канала, в своих проектиках 👍 Моё огромное спасибо автору, не был бы я нищебродом - обязательно бы задонатил.
@SowilTM
@SowilTM 4 ай бұрын
Очень доходчиво объясняете, спасибо. Про паттерны у вас лучшее объяснение, надеюсь данная тема будет у вас продолжаться, хотелось бы про структурные паттерны. Желаю успехов каналу! p.s. Надеюсь с тапком все ок))
@sergeykazantsev1655
@sergeykazantsev1655 4 ай бұрын
Спасибо за тёплые слова) Тапок в порядке :D
@darkhaunt9930
@darkhaunt9930 5 ай бұрын
Стейт машина, по моему скромному, должна учится применяться начинающим джунам как можно скорее, потому что меня удивляет, как человек годами может решать задачи путём создания 5 булок, вместо лаконичного и давно известного решения По различиям стратегии и стейта, считаю что стейт подходит для описания поведения одной цельной и неразрывной сущности, а стратегия - для описания изменчивого аспекта какой-то сущности, или семейтсво алгоритмов Писал я как-то раз условный скролер, где использовал стейт машину для описания состояний оружия - стрельба, перезарядка, простой, заклинило и тп. А для реализации логики стрельбы использовал стретегию. Соответственно при подборе какого бонуса, допустим тройного выстрела, я просто менял реализации стрельбы с одной на другую прям на ходу. Вышло довольно занятно Ну и как всегда спасибо за контент!
@Kondratyevv
@Kondratyevv 5 ай бұрын
и шо много заработал?
@user-to7ic4jy4p
@user-to7ic4jy4p Ай бұрын
Спасибо большое за лаконичное объяснение паттерна, очень полезно! На смузи закинул)
@sergeykazantsev1655
@sergeykazantsev1655 Ай бұрын
Душевно благодарю) получил)
@MrG12g
@MrG12g 5 ай бұрын
Молодец!! Самое лучшее объяснение паттерна state на ютубе
@Oscar-ll6mt
@Oscar-ll6mt 5 ай бұрын
Спасибо, за твои уроки, очень понятно и интересно.
@ctpaxru7067
@ctpaxru7067 5 ай бұрын
Спасибо за видео, увидел немного другую реализацию этого патерна (я делал переключение не энамах, а на словаре с типами). Постоянно юзаю этот паттерн в самой основе архитектуры игры (BootstrapState, LocationLoadState, ActiveGameState, PauseState итд). В любом случае спасибо, автор молодец!
@delmas237
@delmas237 4 ай бұрын
Спасибо! Коммент для продвижения)
@forcesoftheevil9252
@forcesoftheevil9252 5 ай бұрын
+REP за сравнения State и Strategy. На собесах спрашиваюь (мидл). От себя добавлю: не использовать синдикатовскую машину - циклическая зависимость.
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
А что такое синдикатовская машина? Оо
@forcesoftheevil9252
@forcesoftheevil9252 5 ай бұрын
@@sergeykazantsev1655 K-syndicate. Чуваки сформулировали архитектуру и создали свой DI. Работяги при переписывании архитектуры на Zenject сталкиваются с циклическими зависимостями. Да и я сам так делал... и на VContainer пытался их машину написать...
@bornumental146
@bornumental146 5 ай бұрын
@@sergeykazantsev1655 Думаю он про K-Syndicate
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
Понятно, надо будет посмотреть чего они там наворотили)
@IAteVideoGames
@IAteVideoGames 5 ай бұрын
Канал обалденный, все видосы посмотрел. Обязательно продолжай! Можешь ли посоветовать какие-то материалы почитать для углубления знаний по архитектуре проекта? Как правильно делать и т.д.
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
могу посоветовать видео Евгения Дубовика kzfaq.info/get/bejne/bdGbqpCI3NW0cqc.html но в целом ожидать готовых шаблонов которые можно быстро впитать и начать клепать не стоит есть так же тг канал по архитектуре, его держат очень умные дяди, очень советую t.me/unity_architecture
@IAteVideoGames
@IAteVideoGames 5 ай бұрын
@@sergeykazantsev1655 Спасибо большое! В группу вступил, буду ждать новых роликов. Успехов!
@issatay8876
@issatay8876 5 ай бұрын
Не посмотрел, но видос крутой
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
а как ты это понял? :D
@titanovsky
@titanovsky 5 ай бұрын
Новое видео)
@rdragon587
@rdragon587 4 ай бұрын
Cool)
@Mr_TroubleMaker
@Mr_TroubleMaker 5 ай бұрын
Классный ролик как всегда. Но есть несколько вопросов =) : 1. Зачем вообще разные методы, если у нас будет расширяться функционал, то мы будем вносить изменения в каждый класс, что нарушает OCP??? Ведь в состояние можно зайти и выйти + постоянное обновление состояния. Следовательно всего 3 метода в базовом классе (Enter, Exit, Tick(float delta)). Если ещё дженериковые стейты сделать, то вообще будет песня, типа State. И добавить класс FSM у которого есть словарь Dictionary , текущее состояние , сетер стейта, методы добавления/ получения текущего и обновление текущего стейта. Если не брать в расчёт первый вопрос и продолжить смотреть текущий вариант, то другой вопрос. 2. Почему все абстрактные методы? ведь это обязывает реализовать метод, а как видели в видео там есть состояния у которых нет реализации, возможно стоит делать виртуальными чтобы не засорять класс-наследник?
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
1. С моей точки зрения, OCP не запрещает нам вносить изменения в класс. OCP запрещает нам изменять старую логику при модификации, а новая логика в существующем классе - это не изменение а то самое расширение. Если понимать OCP дословно, то тогда на каждый чих нужно будет наследоваться от написанного класса и это будет очень больно и трудно 2. Потому что по хорошему надо так организовать абстракцию чтобы любое состояние как-то выполняло тот или иной метод, и не было пустых. Туда например можно воткнуть Error-ы и информацию о том что починить активную башню невозможно. В конкретном примере да, можно сказать что нарушается LSP и ISP, но виртуальные методы мне кажется всё же мешают ясности и пониманию как то или иное состояние реагирует на тот или иной метод
@Mr_TroubleMaker
@Mr_TroubleMaker 5 ай бұрын
​@@sergeykazantsev1655 1. По текущему примеру. Нужно добавить Поиск врага/ в процессе строительства/починки/ атака врага / оборона - всё это придётся вносить в каждый стейт, а оно нужно ли каждому стейту? А есть уже 20 состояний, придёт ГД и такой давай сделаем чтобы башня при здоровье меньше 10 % усиливала дамаг и издавала спасательные звуки и придётся в 21 классе что-то писать, вместо того чтобы создать 1 класс нового состояния и когда здоровье меньше 10% просто сказать эй башня го в состояние такое-то = ) 2. При абстрактном классе с пустым виртуальным методом ничего не сломается при вызове метода базового класса, следовательно если в наследнике будет или нет конкретная реализация то она корректно отработает в любом случае. Лучше в абстрактном классе оставить пустой виртуальный метод, чем прописывать эесепшены или возвращать null/default в каждом наследнике.
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
1. Поиск врага не требует, чтобы его по разному реализовали разные состояния, я бы для поиска и стрельбы либо сделал бы флаг CanAttack либо вообще стрелял только если бы state = active То же самое касается усиленного урона, поведение урона башни не зависит от состояния, он зависит от хп, потому той проблемы что вы написали не будет)
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
2. С вашими аргументами согласен, но как и писал ранее, в идеале абстракция должна быть такой чтобы ни виртуальных методов, ни return null ни эксепшнов не было) но это в идеале
@Mr_TroubleMaker
@Mr_TroubleMaker 5 ай бұрын
@@sergeykazantsev1655 это геймдев, идеальных проектировок не будет =) постоянно что-то меняется
@mibixdev
@mibixdev 5 ай бұрын
А какую тему в VS Code используете? И может дадите какие-то советы/рекомендации по настройке VS Code для Unity?
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
Я установил несколько плагинов для более удобной разработки. Ничего волшебного и сверх крутого - просто автоподставка текста, цветовая тема из райдера, хоткеи из Visual Studio. Если интересно - можете написать мне в тг, я скину вам профиль в VS Code, если вы его загрузите у вас будет то же самое)
@ctpaxru7067
@ctpaxru7067 5 ай бұрын
@@sergeykazantsev1655 Почему вы перешли на VSCode с Райдера (просто всегда видел, как наоборот, на Райдер перехдят). И как VSCode в плане удобства в сравнении с ним?
@sergeykazantsev1655
@sergeykazantsev1655 4 ай бұрын
Райдер лучше, но VS Code бесплатный :D
@ktotakoi6037
@ktotakoi6037 5 ай бұрын
А почему нельзя то, что реализовано в отдельных классах, запихать в методы и переключать их присваивая делегату определенный метод? Тогда прийдется дописывать еще методы для перехода состояний, получается у состояния есть дополнительно логика для его включения и выключения?
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
Ну там может быть слишком много логики, чтобы в методы запихивать. В той же игре про шаурму - представьте ход врага и игрока в методы запихивать - повеситься можно)
@ktotakoi6037
@ktotakoi6037 5 ай бұрын
Несколько раз пересмотрел и понял что я про стратегию подумал.
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
бывает)
@U7Craft
@U7Craft 5 ай бұрын
Паттерн Состояние больше похож на паттерн Команда, чем на Стратегию, имхо)
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
А в чём, по вашему, схожесть команды и состояния?)
@U7Craft
@U7Craft 5 ай бұрын
@@sergeykazantsev1655 По назначению, конечно, абсолютно разные) Но, с точки зрения структуры очень даже похожи. За каждое состояние отвечает отдельный класс, также и для каждой команды выделяется собственный класс В классе контекста переключатель состояния выглядит вроде "SetState(new Idle(args))", и аналогично команда выглядит "Send(new InitCommand(args))".
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
ну в этом да, полиморфизм во всей его красоте)
@user-mu2du3np7d
@user-mu2du3np7d 5 ай бұрын
Спасибо за работу. Доставляет. Вопрос более общего плана. Как научиться уметь в архитектуру? Просто есть уровень условного Brackeys, когда главное заставить чтоб оно заработало, и пофиг что там внутри. И есть уровень когда все уже трут за чистую архитектуру, шаблон инжект и прочий космос. Может кто подскажет дорогу, как попасть на второй уровень? Отдельно по запчастям слушаешь, смотришь -все понятно. А откроешь любой проект с гитхаба с примером игрушки построеной по шаблонам, архитектуре и т.д. - и капец. Куда смотреть, как понимать, что за кого отвечает и зачем вообще нужно? Непонятно, одним словом
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
По архитектуре мое мнение что все упирается в опыт, и чтобы уметь в архитектуру, либо тебе этот опыт кто-то должен передать (лид, ментор) который будет смотреть ваш код, бить по рукам, и объяснять почему так, либо этот опыт надо получить самому. Во втором случае вы пишете игру и в какой то момент понимаете что дальше расширять игру очень сложно и неудобно. В этот момент вы пытаетесь понять почему это произошло, возвращаетесь к теории и понимаете о чем писалось в книжках и про что эти ваши паттерны и SOLID. К счастью или сожалению, архитектуры не стандартизированы, потому тут нет четких шаблонов как в тех же паттернах, все пишут что-то свое но делиться не спешат ибо часто это корпоративная тайна) я так думаю, мне так кажется
@user-mu2du3np7d
@user-mu2du3np7d 5 ай бұрын
Спасибо за ответ А случаем нет волшебного пенделя в виде книги, тутора(eng, ru) с более широким пояснением на конкретной задаче, игре. Почему тут так, а туда лучше пока совсем не надо и т.д. И по типу, чтоб начать - пойдем отсюда, потому что... Я то понимаю, что пендель на самом деле = практика своей головой и руками. Но может есть хоть путеводная тропа))
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
К сожалению, я не смотрел современные курсы по юнити потому не знаю, как там обстоят дела Есть тг канал по архитектуре в юнити, может обсуждения или прикрепленные ресурсы вам помогут t.me/unity_architecture
@ktotakoi6037
@ktotakoi6037 5 ай бұрын
Зачем хранить состояние в словаре? Почему не использовать статический класс? Синглтон это слишком)
@sergeykazantsev1655
@sergeykazantsev1655 5 ай бұрын
Не состояние в словаре, а пул всех созданных состояний. Условно если у нас 5 состояний и если мы между ними переключаемся, лучше их сохранить в коллекции, а не пересоздавать заново каждый раз.
@ktotakoi6037
@ktotakoi6037 5 ай бұрын
@@sergeykazantsev1655 А статика не пойдет - потому что экземпляров обьектов может быть много, и тогда все состояния будую для всез одинаковы, понял.