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

2020 ж. 18 Мау.
42 680 Рет қаралды

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

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

    @insaneone-7220@insaneone-72203 жыл бұрын
    • Дополню, UnityEvent выгоден если только один объект подписан на него, в любых других случаях он проигрывает в произовидельности остальным делигатам

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

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

    @ithangover589@ithangover5893 жыл бұрын
    • для начинающего не подходит.

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

      @rezenkron@rezenkron Жыл бұрын
    • урок не очем, автор урока просто кэп, а в тонкостях сам видать не шарит

      @Bushido_Cat@Bushido_Cat7 ай бұрын
    • лучший коммент на этом видео + 50% к информативности к видео)

      @morphidevtalk@morphidevtalk5 ай бұрын
  • Спасибо за видео и объяснение

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

    @user-mn7dx7xf7j@user-mn7dx7xf7j3 жыл бұрын
  • Спасибо за видос!!! Искал эту тему долго...

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

    @Gladiusspb@Gladiusspb3 жыл бұрын
  • колокол стоит, ждемс юнити ивентс

    @ThePirateHistory@ThePirateHistory3 жыл бұрын
  • Божественно подаёшь инфу))

    @user-cu5ky8qz2n@user-cu5ky8qz2n3 жыл бұрын
    • О, димас, дарова)

      @Sqeje@Sqeje2 жыл бұрын
  • круто,спасибо!Лайк и подписка)

    @user-ij8vr8ss8s@user-ij8vr8ss8s2 жыл бұрын
  • спасибо за лекцию, смог написать курсач без плагиата

    @mr.dandomi@mr.dandomi3 жыл бұрын
  • Хорошая подача, ничего лишнего! Спасибо!

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

    @user-nz1lx8iq8b@user-nz1lx8iq8b3 жыл бұрын
  • Пиздатый урок, продолжай в том же духе

    @sphonernn7023@sphonernn70233 жыл бұрын
  • Спасибо!

    @mikel8205@mikel82053 жыл бұрын
  • Канал - ТОП!

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

    @user-hp3kt3ot7d@user-hp3kt3ot7d3 жыл бұрын
  • Офигенчик👍

    @siwer1768@siwer17683 жыл бұрын
    • Какие люди в Голливуде)

      @nesterscodestudio6274@nesterscodestudio62743 жыл бұрын
  • Ещё один годный урок! Приятно и понятно. Лайк подписка не глядя!

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

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

    @psy_gamer@psy_gamer3 жыл бұрын
    • Записал в список идей для будущих видео)

      @insaneone-7220@insaneone-72203 жыл бұрын
  • Спасибо большое, очень доступно, подробно и сжато.

    @YasnaKo@YasnaKo3 жыл бұрын
  • Подача супер, но хотелось больше практических применений.

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

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

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

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

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

      @insaneone-7220@insaneone-72203 жыл бұрын
    • @@insaneone-7220 поэтому не лениться и отписываться всегда)

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

    @user-ll1ms8qi2f@user-ll1ms8qi2f3 жыл бұрын
  • Наверное единственный, кто объяснил и показал понятно и кратко.

    @theRealArtyomkar@theRealArtyomkar3 жыл бұрын
  • Подача огонь. красиво. Спасибо.

    @user-hi9zu7el9e@user-hi9zu7el9e2 жыл бұрын
  • Где же ты пропал? Почему у меня юнити не видит синтаксис слова "singleton"?

    @Black_Raven-@Black_Raven-2 жыл бұрын
  • когда новые видео?

    @NoName-sb7vf@NoName-sb7vf3 жыл бұрын
  • Откуда взялся Play на 2:05???

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

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

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

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

      @omoloni@omoloni3 жыл бұрын
    • @@combine_soldier напрямую поле хп меняешь или через функцию? И ию аптечка меняет?

      @AlexStraga@AlexStraga2 жыл бұрын
    • @@combine_soldier это тема тогда)

      @AlexStraga@AlexStraga2 жыл бұрын
  • А есть видео про полиморфизм?

    @YasnaKo@YasnaKo3 жыл бұрын
  • всё красиво Но "Не поняяятно"

    @user-yg9rq6xn3o@user-yg9rq6xn3o3 жыл бұрын
  • супер. за 5 минут объяснил то что другие по полчаса разжевывают

    @blinstas@blinstas3 жыл бұрын
  • Код подольше показывай, на паузу постоянно приходится ставить

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

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

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

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

      @insaneone-7220@insaneone-72203 жыл бұрын
  • помедленнй Я пытаюсь понять

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

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

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

      @user-hp3kt3ot7d@user-hp3kt3ot7d3 жыл бұрын
    • @@user-hp3kt3ot7d можно попробовать) Почта в разделе "О канале" на странице канала, можно на неё отправить

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

    @mr.frankenstein8967@mr.frankenstein89673 жыл бұрын
  • Зачем делегат? Я пользуюсь unityevent. Там всё просто и не замороченно. И без всяких делегатов

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

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

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

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

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

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

      @insaneone-7220@insaneone-72203 жыл бұрын
    • @@insaneone-7220 а ларчик просто открывался...

      @ElChampi0@ElChampi03 жыл бұрын
    • @@insaneone-7220 а ещё вопрос: а как сделал Player.singelton?

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

      @jagerkat@jagerkat3 жыл бұрын
  • А как отписываться от событий, если на них в старте подписываемся?

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

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

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

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

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

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

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

    @morphidevtalk@morphidevtalk5 ай бұрын
  • Привет нормализации input

    @lopiktest5193@lopiktest51935 ай бұрын
  • А разве UnityEvent не удобнее?

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

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

      @alexalexgood@alexalexgood2 жыл бұрын
  • Плохо код объясняешь.

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

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

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

      @insaneone-7220@insaneone-72203 жыл бұрын
    • @@insaneone-7220 Понял))

      @Vladislav-Listev@Vladislav-Listev3 жыл бұрын
    • Скрипт стал активным, подписался, его улалили или сделали неактивным - отписался. Поэтому в onEnable/disable самое то подписки мутить.

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

      @ithangover589@ithangover5893 жыл бұрын
    • @@insaneone-7220 Изучи код конвенсию от майкрософта раз пишешь на C#.

      @ithangover589@ithangover5893 жыл бұрын
  • та

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

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

    @unitypie3355@unitypie33552 жыл бұрын
KZhead