Продвинутый C# в Unity - События

Поделиться
HTML-код
  • Опубликовано: 29 сен 2024
  • Рассказываю про события в языке программирования C#, используемом в Unity. Их использование при создании игры поможет упростить код и сделать его более логичным и понятным, а так же облегчит создание некоторых взаимодействий.
    Поддержать канал на русскоязычном Boosty: boosty.to/insa...
    Или на Patreon: / insaneone
    Discord-сервер канала: / discord
    Группа VK: insaneo...
    У меня на канале регулярно выходят новые видео с уроками по Unity и разработке игр, а так же другими интересными темами, связанными с геймдевом. Подписывайся!
    Не забывай оставлять комментарий, если у тебя появились вопросы или предложения по видео :)
    #Unity #CSharp #РазработкаИгр

Комментарии • 111

  • @insaneone-7220
    @insaneone-7220  4 года назад +23

    Привет! Начал новую серию уроков, в которой рассмотрю продвинутое использование C# в Unity. Под продвинутым я понимаю не что-то сложное, а скорее способы упростить разработку, к которым приходишь с опытом создания игр. Кстати, я специально не стал в видео говорить ничего про UnityEvents, поскольку думаю показать их подробно в отдельном ролике. А новый урок по оптимизации уже скоро! :)

    • @ProkerKusaka
      @ProkerKusaka 4 года назад

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

    • @WebBestMaster
      @WebBestMaster 2 года назад

      видос хороший, НО вот лично мне реально пришлось "догугливать" что бы до конца разобраться ибо пример совсем плохо разобран (( НО, всё равно, спасибо) теперь я знаю чуть-чуть больше))

  • @ithangover589
    @ithangover589 4 года назад +76

    Несколько моментов
    1) Не рассказал нормально про роль делегата в ивенте. Два слова с них не понял ничего.
    2) Есть альтернатива записи ивентов, более приятная "public event Action OnKillMe;
    " , одна строчка те же действие, готовое системное решения которое подходит под 90 процентов решения задач
    3) Не рассказал что в ивентах можно передавать значения при вызове событий.
    4) Отписка событий, это очень важно особенно в юнити. Ибо новички которые будут смотреть видос понаставляють событий, после не будут понимать чё у них вместо одной монетки даёт 4, а он просто не отписался.
    Для продвинутого не очень, для начинающего мб.

    • @GGamess
      @GGamess Год назад +2

      для начинающего не подходит.

    • @rezenkron
      @rezenkron Год назад +2

      Да у него обычно хорошо выходит вкратце и понятно изложить смысл но тут явно слишком урезал важные моменты

    • @Bushido_Cat
      @Bushido_Cat Год назад

      урок не очем, автор урока просто кэп, а в тонкостях сам видать не шарит

    • @morphidevtalk
      @morphidevtalk 9 месяцев назад

      лучший коммент на этом видео
      + 50% к информативности к видео)

    • @wsxpocxeafx
      @wsxpocxeafx 3 месяца назад

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

  • @psy_gamer
    @psy_gamer 4 года назад +1

    Делегаты наше все!
    Крайне полезная структура, которая очень сильно порой помогает решить многие проблемы) Я так делал пошаговую игру через события, было интересно)
    У меня предложение: есть игры на создание каких-либо алгоритмов (по-типу, собери действия игрока, а потом запусти и проверь, что вышло).
    Мог бы ты сделать подобный ролик, где подробно бы объяснялось это?

    • @insaneone-7220
      @insaneone-7220  4 года назад +2

      Записал в список идей для будущих видео)

  • @ОлексійВискворкін
    @ОлексійВискворкін 4 года назад +1

    Пока что не вижу применения этого для себя,но вдруг пригодится =)

    • @AlexStraga
      @AlexStraga 4 года назад +4

      Чел, когда я узнал про такую штуку то я подумал "Почему я не сделал себе этого раньше?! Сделай и себе!")
      Как минимум, гг ударили и надо изменить в интерфейсе его жизни. Да, можно каждый кадр проверять скок хп и... это не сильно ударит по производительности. Вообще. Но ты начинаешь потом еще проверки сувать в апдейты, и еще и еще. И вот тут начинаются лишние вычисления. Поэтому если 1 классу надо знать что что-то изменилось во втором, то первый создает событие и просто вызывает.
      по аналогии с ютубом прикинь автор каждому будет звонить и говорить что вышел новый ролик? )
      Короче топ тема. Можешь прочесть про паттерн Observer (Наблюдатель ) если я не ошибаюсь. Чуть больше гемора в начале пока прописываешь кажется, но это окупается. ;)

    • @omoloni
      @omoloni 4 года назад

      @@AlexStraga согласен, если нет подписчиков, то и никому звонить не надо; и если ни на кого не подписан, а так обзванивать десятки каналов ..., ладно если несколько каналов или подписчиков, то можно и позвонить, иначе будет лень набирать

    • @AlexStraga
      @AlexStraga 2 года назад

      @@combine_soldier напрямую поле хп меняешь или через функцию? И ию аптечка меняет?

    • @AlexStraga
      @AlexStraga 2 года назад

      @@combine_soldier это тема тогда)

  • @liroxyplay8068
    @liroxyplay8068 4 года назад

    Ещё один годный урок! Приятно и понятно. Лайк подписка не глядя!

  • @tasty9555
    @tasty9555 3 года назад

    Откуда взялся Play на 2:05???

  • @alex_konor2197
    @alex_konor2197 Год назад +5

    Плохо код объясняешь.

  • @supromental
    @supromental 2 года назад +1

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

  • @Shirosugia
    @Shirosugia 4 года назад +9

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

    • @insaneone-7220
      @insaneone-7220  4 года назад +2

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

    • @omoloni
      @omoloni 4 года назад +1

      @@insaneone-7220 согласен зачем создавать событие и сразу после этого события отписываться, для того чтобы оно не сработало второй раз

  • @ThePirateHistory
    @ThePirateHistory 4 года назад +8

    колокол стоит, ждемс юнити ивентс

  • @СергейПо-х2и
    @СергейПо-х2и 3 года назад +2

    помедленнй Я пытаюсь понять

  • @eugenekrutoy1475
    @eugenekrutoy1475 4 года назад +15

    Подача супер, но хотелось больше практических применений.

  • @Геймдевивсе-все
    @Геймдевивсе-все 4 года назад +2

    Кстати, в тексте видео, небольшая ошибка: описывается одно поведение, а в показывается другое. Object.SomeEvent += OnSomeEventDo и this.AddListener(SomeEvent, OnSomeEventDo).
    В первом случае, если целевой скрипт будет удален, возникнет ошибка, во втором, как раз нет.

  • @Vladislav-Listev
    @Vladislav-Listev 4 года назад +6

    Что-то разочарован. Ужасный код стайл. Публичные поля/свойства должны быть в Pascal Case, все private поля должны быть помечены как private, что rider делает автоматически, но ты даже с ним умудрился обкакаться) Если уж берешь какие-то компоненты с объекта (аниматор например), то явно вырази договор о том, что данный компонент обязательно должен присутствовать атрибутом RequireComponent. Очень редко, когда действительно нужно писать свой делегат, т.к. делегаты Action, Func и Predicate закрывают большинство случаев, а если нужно добавить подписку в инспекторе, то можно использовать UnityEvent. Как тут уже в комментариях отметили ничего не сказал про отписку. Для подписок и отписок принято использовать OnEnable и OnDisable, а не Awake/Start, сами гуглите почему, я хз)

    • @insaneone-7220
      @insaneone-7220  4 года назад +3

      Публичные поля в Unity пишутся с маленькой буквы, и если писать свои с большой, код будет неконсистентен. Не вижу ни одной причины использовать private кроме лишнего удлинения кода, я перенастроил райдер на обратный кодстайл. Сама такая возможность говорит, что нет единственно верной истины. RequireComponent не требуется, если есть своя, более удобная реализация автоматической настройки компонентов, в данном случае это просто не нужно, т.к. урок не об этом. Насчёт Action действительно стоило сказать. Про UnityEvent я уже писал в закреплённом комментарии. По поводу "я хз" - без комментариев.

    • @Vladislav-Listev
      @Vladislav-Listev 4 года назад

      @@insaneone-7220 Понял))

    • @AlexStraga
      @AlexStraga 4 года назад +1

      Скрипт стал активным, подписался, его улалили или сделали неактивным - отписался. Поэтому в onEnable/disable самое то подписки мутить.

    • @ithangover589
      @ithangover589 4 года назад

      @@insaneone-7220 Что в каком код стайле ПУБЛИЧНЫЕ поля пишутся с маленькой буквы? Что за дичь и ересть?
      С github официального microsoft,
      "Names of classes, methods, enumerations, public fields, public properties, namespaces: PascalCase."

    • @ithangover589
      @ithangover589 4 года назад

      @@insaneone-7220 Изучи код конвенсию от майкрософта раз пишешь на C#.

  • @ElChampi0
    @ElChampi0 3 года назад +6

    Код подольше показывай, на паузу постоянно приходится ставить

  • @severyss_fgi5924
    @severyss_fgi5924 Год назад

    Объяснил очень плохо, для новых программистов будет непонятно, так что старайся объяснять подробнее. Само видео сделано качественно и на уровне, так что в этом молодец.)

  • @The_Mavrik
    @The_Mavrik 2 года назад

    Зачем делегат? Я пользуюсь unityevent. Там всё просто и не замороченно. И без всяких делегатов

  • @pantsurevolution
    @pantsurevolution 2 года назад

    Создаем одно событие, а подписываемся уже на другое, и вообще без предупреждения. Зачем вообще? Так мозги сломать можно.

  • @DarkIllusoire
    @DarkIllusoire 2 года назад

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

  • @unitypie3355
    @unitypie3355 2 года назад

    Это не нормальный рассказ старичок, больше применения нужно. Слишком отрывочно у тебя.

  • @morphidevtalk
    @morphidevtalk 9 месяцев назад

    ролик хорошо обьясняет ЗАЧЕМ их использовать и +- КАК, но ЧТО это плохо совсем

  • @ЕдуардБездухов
    @ЕдуардБездухов 4 года назад +2

    (Заранее пардон за мой кривой русский) Спасибо, что делаешь это - твой контэнт шикарен. Мне очень помогли уроки по оптимизации. Буду и дальше смотреть этот канал)

  • @lopiktest5193
    @lopiktest5193 10 месяцев назад

    Привет нормализации input

  • @СергейПо-х2и
    @СергейПо-х2и 3 года назад +1

    всё красиво Но "Не поняяятно"

  • @NoName-sb7vf
    @NoName-sb7vf 3 года назад +1

    когда новые видео?

  • @Димас-ТвойРазработчикИгр

    Божественно подаёшь инфу))

    • @Sqeje
      @Sqeje 3 года назад

      О, димас, дарова)

  • @Black_Raven-
    @Black_Raven- 2 года назад +1

    Где же ты пропал? Почему у меня юнити не видит синтаксис слова "singleton"?

    • @wsxpocxeafx
      @wsxpocxeafx 3 месяца назад

      Потому что это в его классе, похоже, он объявлен, просто нам не показали.

  • @mr.dandomi
    @mr.dandomi 3 года назад +1

    спасибо за лекцию, смог написать курсач без плагиата

  • @АртурГагиев-ж7я
    @АртурГагиев-ж7я 4 года назад +1

    Вот это я понимаю, полезный видос!! Спасибо тебе!) лойс, подписка!

  • @Gladiusspb
    @Gladiusspb 4 года назад +8

    Огромное спасибо! Только не бросай пожалуйста, доведи до конца то, что запланировал изначально. По содержанию видео - всё великолепно! Просто и с примерами. Так держать!

  • @tonicoders991
    @tonicoders991 4 года назад +1

    Ничего не понял после делегатов. Поидее я уже юзаю Юнити Ивенты и как бы всё работает,но ты толи спешишь,то ли что я рано встал. Не понял зачем писать этот самый делегат? Я просто вешаю слушатель на создаваемое событие. MyEvent.AddListener(()=>myEventResult()); И ещё,что за Singlton на экземпляре Player? Я подобное видел только у тебя. О.о

    • @insaneone-7220
      @insaneone-7220  4 года назад +2

      Ну, точка зрения "я уже юзаю и вроде бы работает" говорит о том, что стоит подробнее изучить вопрос, если это интересует конечно) Обычные ивенты и юнити ивенты похожи, но это немного разные вещи. Юнити-ивенты медленнее работают, например. Обычные ивенты есть в самом C# и при переносе кода в другое приложение, смогут работать и без юнити.
      В твоём примере укороченный делегат сделан через лямбду с помощью конструкции () =>. Да, так можно, но мне же надо было в уроке сказать о том, как это делается без синтаксического сахара? :)
      Singleton это обычный и самый лёгкий паттерн проектирования для доступа к конкретному и единственному экземпляру объекта через статичную переменную, на канале есть видео про его.
      Для понимания этого видео знать про него, в общем, не обязательно. Надеюсь, стало чуть понятнее)

    • @tonicoders991
      @tonicoders991 4 года назад

      @@insaneone-7220 ,вот как. Да,стало чуть яснее. Значит методы из самого языка работают быстрее чем методы которые есть в движке? О.о
      Это как-то объясняется?
      Как например не юзать camera.main и FindObjectsType?
      Потому что это всё немного путает.
      Мол,зачем тогда они вообще нужны,если только делают хуже?
      На самом деле вопросов у меня много. Скорей всего потому-что я новичок в Юнити. И если не ответишь,то я пойму. Не охота лишний раз напрягать человека,которому может не интересно мне всё разжовывать.
      Заранее,спасибо за предыдущий ответ.

    • @insaneone-7220
      @insaneone-7220  4 года назад

      @@tonicoders991 да, ивенты из языка быстрее тех, что в движке. Можно конечно это объяснить тем, что ивенты из юнити удобнее и доступны ещё и из редактора, но на самом деле это не объясняет их медлительности. Возможно, команда юнити недостаточно хорошо их реализовала.

  • @AlexStraga
    @AlexStraga 4 года назад +1

    Можно юзать UnityAction чтобы не создавать виды делегатов. Сразу например пишешь UnityAction и не паришься. event вроде нужен чтобы это событие мог вызвать только класс внутри которого он находится.
    И да, ты не сказал что крайне важно не забывать отписываться от события, иначе хана потом памяти будет)

    • @insaneone-7220
      @insaneone-7220  4 года назад +1

      Да, вариант с UnityAction (Или просто Action, который в namespace System есть) даже удобней в основном. А насчёт отписки - если классы с ивентами или классы-подписчики уничтожаются, то в целом ничего фатального если не отписаться не произойдёт, например после смены уровня все не-статик ивенты пропадут. А вот статики отписывать в строгом порядке, если они существуют)

    • @AlexStraga
      @AlexStraga 4 года назад

      @@insaneone-7220 поэтому не лениться и отписываться всегда)

  • @RunBull
    @RunBull 2 года назад

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

  • @mr.frankenstein8967
    @mr.frankenstein8967 3 года назад

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

  • @siwer1768
    @siwer1768 4 года назад +2

    Офигенчик👍

  • @dmitriybelousov7246
    @dmitriybelousov7246 3 года назад

    День добрый ! Интересно с вами пообщаться на тему совместной работы над проектом...

  • @alexspeleers
    @alexspeleers 4 года назад

    ZENJECT/UNIRX нет годных видеоуроков, только от infalable labs но там без примеров нормальных (:

  • @shved54415
    @shved54415 4 года назад +1

    та

  • @cg_community
    @cg_community 3 года назад

    мог бы код не дергать сторону увеличения и уменьшения

  • @RunBull
    @RunBull 2 года назад

    что такое singleton. у меня ошибка "event1" не содержит определение для "singleton". [Assembly-CSharp]

    • @wsxpocxeafx
      @wsxpocxeafx 3 месяца назад

      Создай SerializedField в классе и в Юнити повесь ссылку на своего игрока.

  • @makarmolochaev1222
    @makarmolochaev1222 2 года назад

    Спасибо за видос!!! Искал эту тему долго...

  • @bogdan9423
    @bogdan9423 Год назад

    Спасибо за видео и объяснение

  • @МарияЯскевич-с9ч
    @МарияЯскевич-с9ч 2 года назад

    круто,спасибо!Лайк и подписка)

  • @YasnaKo
    @YasnaKo 3 года назад

    А есть видео про полиморфизм?

  • @-LGK
    @-LGK 2 года назад

    Привет, я не совсем понял суть, зачем делегаты, если используешь синголтон? можно просто сделать метод

    • @DarkIllusoire
      @DarkIllusoire 2 года назад

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

  • @requiem_for_a_dream5463
    @requiem_for_a_dream5463 2 года назад

    Ты так хорошо объясняешь. Спасибо. А у меня в игре на игроке висит скрипт Interactive. Через рэйкаст это даёт игроку возможность взаимодействовать с другими объектами. Открывать сундуки, двери, подбирать предметы. Так же при подборе предмета выводится звук. Это лучше разбить на отдельные классы и Ивентв или это достаточно взаимосвязано все для одного класса? Мне просто кажется что вроде логично все, но тебе виднее. Интересно узнать твоё мнение. Заранее спасибо

    • @wsxpocxeafx
      @wsxpocxeafx 3 месяца назад

      С чего ты взял, что ему виднее? 😂

  • @sphonernn7023
    @sphonernn7023 4 года назад

    Пиздатый урок, продолжай в том же духе

  • @BaldKrit
    @BaldKrit 4 года назад +4

    Хорошая подача, ничего лишнего! Спасибо!

  • @dmitriygorodov6455
    @dmitriygorodov6455 3 года назад

    А как отписываться от событий, если на них в старте подписываемся?

    • @insaneone-7220
      @insaneone-7220  3 года назад +2

      Можно в OnDisable, но тогда и подписываться лучше в OnEnable. В случае подписки в Start, можно в OnDestroy попробовать.

  • @АлексейАлексеев-ш9ф
    @АлексейАлексеев-ш9ф 4 года назад +3

    Огромное спасибо за полезнейший материал)
    Приятный голос, классная подача)

  • @ЕдуардБездухов
    @ЕдуардБездухов 4 года назад

    Есть вопрос по оптимизации. Делаю раннэр. Собираю мир с елементов (GroundElement) которие состоят из квадов (как шахматная доска). Пол, потолок и стены состоят из 5*6 = 30 квадов каждий (30*4 = 120 квадов в каждом GroundElement). Одновременно на сцене присутствует 24 GroundElement. Вот в чём суть. Все GroundElement меняют свою позицию по мере продвижения игрока, но квады в них относительно родительских объектов (GroundElement) остаються на месте. Это можно как-то оптимизировать (собирать мир не из квадов нельзя)? Заранее благодарю.

    • @insaneone-7220
      @insaneone-7220  4 года назад +1

      Dynamic batching для квадов как минимум. Возможно, такую задачу можно было бы решить шейдером, тогда вместо квадов это была бы одна модель с квадами, двигаемыми в шейдере. Но на мобильных устройствах шейдер не всегда лучший вариант, конечно) Подробнее хотелось бы знать, для чего именно используются квады, чтобы можно было ещё что-то подсказать)

    • @ЕдуардБездухов
      @ЕдуардБездухов 4 года назад

      @@insaneone-7220 я мог бы прислать Вам проект на почту. Если хотите можете даже сделать на него обзор с оптимизацией или чем то ещё. Что скажете?

    • @insaneone-7220
      @insaneone-7220  4 года назад

      @@ЕдуардБездухов можно попробовать) Почта в разделе "О канале" на странице канала, можно на неё отправить

  • @mikel8205
    @mikel8205 3 года назад

    Спасибо!

  • @IGameCrafter3D
    @IGameCrafter3D 3 года назад

    Канал - ТОП!

  • @alexalexgood
    @alexalexgood 2 года назад

    А разве UnityEvent не удобнее?

    • @insaneone-7220
      @insaneone-7220  2 года назад

      UnityEvent работает медленнее шарповых и единственное, чем он удобнее - возможность настраивать из редактора. Но если он больше нравится - ничто не мешает им пользоваться :)

    • @alexalexgood
      @alexalexgood 2 года назад

      @@insaneone-7220 там ещё идёт автоматическая отписка при Destroy. Так что, я так понимаю, если игра не особо нагружена, легче использовать UnityEvent, чтобы не было лишних ошибок

  • @ElChampi0
    @ElChampi0 3 года назад

    А событием на событие можно подписываться? Например нажать кнопку и это событие, на это событие подписано "подобрать монетку", что тоже событие и на это подписан элемент UI который отображает количество монет

    • @insaneone-7220
      @insaneone-7220  3 года назад

      Да. Самое правильное, пожалуй - в методе, подписанном на событие нажатия кнопки, вызвать другое событие. Так вызывать можно сколько угодно событий)

    • @ElChampi0
      @ElChampi0 3 года назад

      @@insaneone-7220 а ларчик просто открывался...

    • @ElChampi0
      @ElChampi0 3 года назад

      @@insaneone-7220 а ещё вопрос: а как сделал Player.singelton?

    • @jagerkat
      @jagerkat 3 года назад

      @@insaneone-7220 день добрый, присоединяюсь к вопросу. Что такое синглтон в принципе понял, но как оформить это как свойство класса?

  • @personificationofweirdness
    @personificationofweirdness 3 года назад +1

    супер. за 5 минут объяснил то что другие по полчаса разжевывают

  • @СергейГуров-ф9п
    @СергейГуров-ф9п 3 года назад

    Подача огонь. красиво.
    Спасибо.

  • @АннаБелохвостик-н6ж

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

  • @theRealArtyomkar
    @theRealArtyomkar 4 года назад

    Наверное единственный, кто объяснил и показал понятно и кратко.

  • @YasnaKo
    @YasnaKo 3 года назад

    Спасибо большое, очень доступно, подробно и сжато.