Паттерн состояния / поведения в C# в Unity. Рассказываю на примерах, как пользоваться

Урок по Unity, посвященный практическим примерам реализации паттерна проектирования под названием состояние или поведение.
Урок по Unity3D, однако именно эта тема подойдет для всех начинающих разработчиков, программирующих на C#.
___
Лавка Разработчика в других соц. сетях, добавляйтесь!
gamedevlavka - вконтактик
t.me/gamedevlavka - телеграм канал Лавки Разработчика
t.me/gamedevtavern - ламповый чат
/ discord - дискорд сервер

Пікірлер: 95

  • @Nikolai2033
    @Nikolai20333 жыл бұрын

    Наконец-то появился нормальный канал с действительно правильным контентом! Паттерны и архитектура на юнити! А не то что эти ваши, сделаем игру за 10 минут!

  • @destar1212
    @destar12123 жыл бұрын

    Огромное спасибо, ты находка, надеюсь еще будут видео про патерны (фабрика, наблюдатель и тд), желаю удачи в своем ремесле и на ютубе

  • @SARDARru
    @SARDARru2 жыл бұрын

    Да, это видео не совсем из ряда "посмотрел, переписал и применяешь" тут нужно додумать, все равно углубиться и понять как это все работает, но не смотря на это, это наверное лучшее что есть на русском. Благодарю, и благодарю что продолжаешь делать видео.

  • @tenko4647
    @tenko46472 жыл бұрын

    Необходимость дописывать код Player при создании нового состояния - грубое нарушение принципа OCP. Методов SetBehavior/StateName/() не должно быть здесь, состояния должны изменяться внутри метода Update каждого состояния. В словаре тоже не вижу смысла, зачем он? Плюс, все, что касается состояний надо вынести из класса Player в класс PlayerBehaviorHandler, для соблюдения принципа SRP. Урок хороший, слушать очень приятно, спасибо!

  • @user-mb9bl3gr9i

    @user-mb9bl3gr9i

    Жыл бұрын

    Крюков в помощь

  • @MARKEDEATH

    @MARKEDEATH

    Жыл бұрын

    откройте форточку

  • @Spaceman68ok

    @Spaceman68ok

    Жыл бұрын

    🤓

  • @artemzaitsev7286
    @artemzaitsev72862 жыл бұрын

    Отличный урок, планирую просмотреть все Ваши видео прежде чем пойти на собеседование)) Удачи в разработках

  • @vladisslavss
    @vladisslavss2 жыл бұрын

    Отличный урок. Спать ибо за труд 🔥✨

  • @arfvewwww2
    @arfvewwww22 жыл бұрын

    Теперь я выучил новый паттерн! Спасибо большое

  • @artemkorotkov9770
    @artemkorotkov97703 жыл бұрын

    ОЧЕНЬ КАЧЕСТВЕННЫЕ ВИДЕО!!!!! УДАЧИ ТЕБЕ ДРУГ!!!! И БОЛЬШОЕ СПАСИБО!!!!!!!

  • @gen_nady
    @gen_nady3 жыл бұрын

    Очень хороший канал, для тех, кто хочет устроиться на работу

  • @gamedevlavka

    @gamedevlavka

    3 жыл бұрын

    В точку!

  • @user-ox6eq9dz8o
    @user-ox6eq9dz8o2 жыл бұрын

    Спасибо, путь благословит тебя Бог на твоем пути.

  • @user-ww3ld6xd6g
    @user-ww3ld6xd6g3 жыл бұрын

    Лучшая реализация state что я видел) Беру на вооружение)

  • @AlexandrFedotov009
    @AlexandrFedotov0092 жыл бұрын

    Это гениально, огромное спасибо!

  • @Kn_Dmitry
    @Kn_Dmitry6 ай бұрын

    Спасибо! Классный урок!

  • @PS-vj6jz
    @PS-vj6jz3 жыл бұрын

    Хорошие видео, как новичку все понятно (новичку в Unity, не в ооп). Честно, тебя приятно слушать и смотреть, с удовольствием бы устроил кросс вечер за просмотром видео. Но их пока мало, нужно исправлять ситуацию)

  • @gamedevlavka

    @gamedevlavka

    3 жыл бұрын

    Спасибо) было бы больше времени, видео выходили бы чаще) к сожалению, пока не могу позволить себе :(

  • @PS-vj6jz

    @PS-vj6jz

    3 жыл бұрын

    @@gamedevlavka потихоньку полегоньку)

  • @annastudenikova376
    @annastudenikova3762 ай бұрын

    Слов нет) Супер урок!

  • @stanislaukorkuts9873
    @stanislaukorkuts9873 Жыл бұрын

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

  • @modjaid3907
    @modjaid39072 жыл бұрын

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

  • @NovaDev-Stormrage
    @NovaDev-Stormrage Жыл бұрын

    Очень круто мужик!

  • @anastasiyak6264
    @anastasiyak62643 жыл бұрын

    Спасибо все ясно .

  • @dmitriykiselyv7645
    @dmitriykiselyv76452 жыл бұрын

    Спасибо, полезно!

  • @alikursak7181
    @alikursak71812 жыл бұрын

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

  • @Sovereing2027
    @Sovereing202710 ай бұрын

    3:22 Оговорочка по фрейду

  • @MrGoldorange
    @MrGoldorange2 жыл бұрын

    Очень круто видео! Люблю твой канал. Если можно поясни пожалуйста. В моем понимании это три состояния в апдейте выполняют какую то движением, следовательно они вероятно имеют доступ ко всяким вещам которые относятся к МоноБехэйвор, так вот стоит их наследовать, прописыват логику там в апдейте и добавлять как компоненты к плееру, либо сразу их закидавать через сериалайзФилд. Или вообще так делать не стоит и можно передавать в них в методе СетБехеивор собственный МоноБехэйвор?

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    Все верно, если тебе изнутри состояния нужно манипулировать трансформом, или игровым объектом, или зечем-то понадобился монобех, то это все просто передается в конструктор, и тогда состояние может им манипулировать.

  • @arazorg4038
    @arazorg40383 жыл бұрын

    Восхитительный контент, буквально закрыл все пробелы на джуна. Переписал проекты для портфолио, ранее утопал в синглтонах. Скоро иду на собеседование, спасибо вам большое. Удачи и развития каналу.

  • @gamedevlavka

    @gamedevlavka

    3 жыл бұрын

    Удачи на собеседовании!

  • @user-cm9hc5kn4i

    @user-cm9hc5kn4i

    2 жыл бұрын

    Как успехи? )

  • @RobinGoodwe872
    @RobinGoodwe872 Жыл бұрын

    Супер

  • @king_fox_3106
    @king_fox_31062 жыл бұрын

    И ещё, по поводу методов SetState ближе к концу можно реализовать интереснее, что бы вызывать один метод, с разными состояниями, задавая их условно через enum или же посидеть подумать, как реализовать прикольнее...

  • @TheGoBender
    @TheGoBender3 жыл бұрын

    Спасибо за урок. Но вот нубский вопрос возникает. Как быть с анимациями? Должны ли мы внутри этих классов подключать еще и StateMachineBehaviour ?

  • @vitaliySobakinson
    @vitaliySobakinson2 жыл бұрын

    Аллах, храни этого пасана

  • @user-mh2ll7cg7x
    @user-mh2ll7cg7x26 күн бұрын

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

  • @jonathansantos6026
    @jonathansantos602611 ай бұрын

    Добрый вечер, я реализовал FSM у персонажа, состояние между собой переключаются,все работает как надо,но возник вопрос... У меня состояние jump, которые никак не могу реализовать,по сути Джамп должен вызываться в любой момент игры,поэтому я хочу вынести Джамп под отдельный компонент,потому что не знаю как можно реализовать состояние,у меня не будет механик по типу двойного прыжка и лазание по стенам... Как ты думаешь лучше подумать и реализовать в машине или лучше вынести его? Заранее спасибо...

  • @king_fox_3106
    @king_fox_31062 жыл бұрын

    По поводу проверки на наличие класса внутри интерфейса, разве нельзя сделать запись что то типо: this.PlayerBehavior?. Update(); Вопрос тип спрашивает, содержится ли в поле что нибудь... Я знаю, что это работает с классами, а с интерфейсами не пробовал. Почему задаю вопрос, потому что можно спросить в if неявно наличие экземпляра Например: if(Class) { выполнение при наличии класса } А с интерфейсами так не работает

  • @GERGONable
    @GERGONable2 жыл бұрын

    Когда люди указывают тип в обощении - они обычно ожидают получить этот тип на выходе а не тип на уровень выше

  • @chernik_us2752
    @chernik_us27523 жыл бұрын

    блин, классно! Слушай а если не секрет, сколько ты лет уже занимаешься c# и юнити ?)

  • @gamedevlavka

    @gamedevlavka

    3 жыл бұрын

    C# 6 лет, unity 5 лет, в данный момент

  • @dmytromahas9207
    @dmytromahas9207 Жыл бұрын

    Можете пожалуйста кто-то объяснить, зачем создавать отдельный метод GetBehaviour ? Можно и без него обойтись, допустим как в методе SetIdleBehaviour: private void SetIdleBehaviour() { SetBehaviour(_behavioursMap[typeof(PlayerIdleBehaviour)]); }

  • @Bushido_Cat
    @Bushido_Cat8 ай бұрын

    А в чем разница, если по итогу у тебя update забит if всеми состояниями?

  • @CiTRyS32
    @CiTRyS322 жыл бұрын

    Мне кажется, вы не очень корректный пример привели, и в данном случае, когда мы сами выбираем куда переключиться, данный паттерн является все же стратегией, состояния это типа как с балансом - мы хотим потратить деньги и уже от условий задаются состояния: 1) хватает - тратятся 2) не хватает - уведомляет 3) есть возможность в минус уходить - оформляется заем и т.д

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    Да, вы абсолютно правы. Это уже обсуждалось в одном из комментариев

  • @janitor13
    @janitor13 Жыл бұрын

    Здраствуйте, сделал небольшой рекфатрониг, что скажете? Кажется этот варинат более привлекательным: public class Player : MonoBehaviour { private Dictionary _behavioursMap; private IPlayerBehaviour _behaviourCurrent; private void Start() { InitBehaviours(); SetBehaviourByDefault(); } private void InitBehaviours() { _behavioursMap = new Dictionary(); _behavioursMap[typeof(PlayerBehaviourActive)] = new PlayerBehaviourActive(); _behavioursMap[typeof(PlayerBehaviourAggressive)] = new PlayerBehaviourAggressive(); _behavioursMap[typeof(PlayerBehaviourIdle)] = new PlayerBehaviourIdle(); _behavioursMap[typeof(PlayerBehaviourDie)] = new PlayerBehaviourDie(); } private void SetBehaviour(IPlayerBehaviour newBehaviour) { if (_behaviourCurrent != null) _behaviourCurrent.Exit(); _behaviourCurrent = newBehaviour; _behaviourCurrent.Enter(); } private void SetBehaviourByDefault() { SetNewBehaviour(); } private void Update() { if (_behaviourCurrent != null) _behaviourCurrent.Update(); } public void SetNewBehaviour() where T : IPlayerBehaviour { var type = typeof(T); SetBehaviour(_behavioursMap[type]); } }

  • @boykopb
    @boykopb2 жыл бұрын

    А можно вопрос, допустим, есть состояния Walk, Run и Attack. Не совсем понятно, а как сочетать Run + Attack или Walk+ Attack?

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    В случае возможности атаковать на ходу, так и прописывается в состоянии Walk, или Run. Прям внутри этих состояний. Но я бы для них сделал некий базовый класс, чтобы код не дублировать

  • @nepochat
    @nepochat2 жыл бұрын

    Получается саму визуализацию (движение игрока, скорость, прыжки) мы реализовываем через компонент состояния? Например мне нужно чтобы PlayerBehaviorActive заставлял персонажа двигаться. Мне нужно привязать к нему Rigidbody2d, а значит сначала поместить этот скрипт на объект персонажа?

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    На игроке будет Rigidbody, и его ссылку передаешь внутрь поведения

  • @nepochat

    @nepochat

    2 жыл бұрын

    @@gamedevlavka понял, а каким методом передавать ссылку?

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    Через конструктор

  • @olsney
    @olsney Жыл бұрын

    Можете пожалуйста объяснить откуда в коде взялось в методе SetBehaviour "behaviourCurrent = newBehavior"? Вот этот нью бехэйвиор - откуда? Это же не опечатка и при этом не объект класса Behaviour, но и красным не подчеркивает

  • @dronsan-unity7302

    @dronsan-unity7302

    Жыл бұрын

    В параметрах метода написан, когда используешь этот метод, ты в него должен прокинуть этот элемент

  • @olsney

    @olsney

    Жыл бұрын

    @@dronsan-unity7302 точно) пропустил этот момент) спасибо

  • @cerf14506
    @cerf145068 ай бұрын

    Вы на полном серьезе создаете сначала Dictionary потому что состояний может быть много, но после вы создаете 3 метода которые будут отвечать за эти состояния, хотя сама их логика должна находиться в классах что унаследовали от интрфейса? А что если у меня 10 состояний под одни только анимации? Я что еще 10 методов написать должен чтобы патерн state работал? А разве он и не создан чтобы децентрализовать код и уменшить количество if и методов

  • @cerf14506

    @cerf14506

    8 ай бұрын

    Изаините что так грубо в начале комментария написал

  • @integer_dev
    @integer_dev3 жыл бұрын

    Пару строчек кода с паттерном стратегия и немного абстракции - верная замена приведенному паттерну. Не вижу в нем необходимости, по крайней мере в данном примере

  • @gamedevlavka

    @gamedevlavka

    3 жыл бұрын

    Шаблоны стратегия и состояние (поведение) очень похожи. Существуют для разных задач: стратегия отвечает на вопрос "Как делать что-то при определенной стратегии", а состояние - "Что делать в определенном состоянии". Ключевое отличие в том, что паттерн состояния может сам переключать состояние своего "владельца", то есть например: когда закончится атака, состояние атаки переключит персонажа в состояние спокойствие. Стратегия так не работает. Согласен, переключение состояний "изнутри" не показано в примере, я решил, что это долго, и не стал этого делать, показал лишь идею самого паттерна, для чего он нужен.

  • @sadamskech6351

    @sadamskech6351

    2 жыл бұрын

    @@gamedevlavka Вообще не так это нужно реализовывать состояния для игрока. Нужно использовать State Machine Behaviours!!!

  • @andrey_aka_skif

    @andrey_aka_skif

    Жыл бұрын

    @@gamedevlavka без состояний, которые знают о других состояниях, паттерн де-факто вырождается в Стратегию. Да, Банда Четырех не конкретизирует, кто именно должен определять переход. Но они пишут, что правильнее и гибче позволить конкретным состояниям управлять переключением. На Рефакторинг-Гуру так и вовсе называют Состояние надстройкой над Стратегией. В том смысле, что это и есть Стратегия, только конкретные "стратегии" знают друг о друге. И ещё одно занятное наблюдение. Методы Start() и Exit() не являются обязательными для паттерна, но фигурируют в большинстве роликов. Кстати, нет в планах ролика об иерархических FSM или Pushdown automaton?

  • @Itibsoft-chanel
    @Itibsoft-chanel3 жыл бұрын

    Довольно неплохое видео. Лишнего вообще ничего нет. Мне понравилось. Спасибо) Слушайте, не хотите взаимно добавить наши каналы в разделе на ютуб канале "Каналы". Думаю это даст взаимное продвижение роликов и развитие общества разработчиков. Ваша аудитория может заметить мой канал, а моя аудитория - ваш!

  • @great8814
    @great88142 жыл бұрын

    Очень круто! Но зачем вы везде пишете this? Это же не обязательно

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    Я постоянно экспериментирую с кодстилем. Пытаюсь поймать баланс: 1. Максимально высокая стабильность 2. Максимально удобный процесс написания. 3. Кодстайл должен не отличаться от кодстайла юнити. Собственно, поэтому где-то есть this, где-то нет. Где-то еще какие-то необычность. Я не сторонник строгого следования кодстайлу Майкрософт. P.S. от this, кстати, я отказался)

  • @user-ml5tn8qn8j
    @user-ml5tn8qn8j Жыл бұрын

    Охуенно! Похоже на ECS

  • @BastionKadabr
    @BastionKadabr Жыл бұрын

    как красиво иначе хреначил все через enum в одном скрипте

  • @nightyonetwothree
    @nightyonetwothree2 жыл бұрын

    в чём прикол делать словарь, если ты потом для каждого элемента создаёшь личную функцию?

  • @asaki1k
    @asaki1k2 жыл бұрын

    вместо того, чтобы создавать кучу методов для каждого состояния, метод взятия, задания состояния по взятому..., да ещё и заводить словарь, можно было обойтись таким методом: public void SetBehavior() where T : IPlayerBehaviour { if (currentBehaviour != null) currentBehaviour.Exit(); currentBehaviour = Activator.CreateInstance(); currentBehaviour.Enter(); }

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    Плохой вариант. Потому что часто внутрь поведения нужно передавать параметры + создание инстанса через активатор - ресурсоемкий процесс, + лишний алокейт памяти, а если внутри префаб какой создаётся, то вообще беда.

  • @asaki1k

    @asaki1k

    2 жыл бұрын

    @@gamedevlavka ок, видимо, я не совсем понял данный паттерн

  • @kingofbattleonline
    @kingofbattleonline2 жыл бұрын

    И зачем ты там использовал this?

  • @gamedevlavka

    @gamedevlavka

    2 жыл бұрын

    Все просто: думал, что удобно. Оказалось, и без this удобно

  • @kingofbattleonline

    @kingofbattleonline

    2 жыл бұрын

    @@gamedevlavka ссылка this используют как объект взять самого себя.

  • @kingofbattleonline

    @kingofbattleonline

    2 жыл бұрын

    @@gamedevlavka и тем не менее, паттерн хорошо реализовали.

  • @user-kf4ye7zy4z
    @user-kf4ye7zy4z2 жыл бұрын

    Очень сложная реализация стэйтмашины

  • @justcore
    @justcore Жыл бұрын

    Правильно behavioUr, а не behavior

  • @gamedevlavka

    @gamedevlavka

    Жыл бұрын

    Первый вариант британский, второй американский другой разницы между этими двумя словами не имеется

  • @justcore

    @justcore

    Жыл бұрын

    @@gamedevlavka Но в Unity куда не посмотри, везде пишут именно Behaviour. Думаю, лучше придерживаться этого для избежания путаницы

  • @sodden_steam
    @sodden_steam2 жыл бұрын

    Послание новичкам: Это видео не для новичков. Инфа хорошая, но объяснений практически ноль.

  • @user-hn6gz8sh7o
    @user-hn6gz8sh7o4 ай бұрын

    Ахаха)) мля, ну ты жесткий конечно. Так усложнить statemashine///

Келесі