5

Система игровых событий

В Unity известен подход ко взаимодействию объектов посредством событий.

Объявляется Action с необходимыми параметрами. Какие-то объекты на него подписываются, кто-то это событие вызывает и все подписчики исполняют методы, которыми подписались на это событие. Такой подход уменьшает связанность объектов, что есть хорошо.

Однако важно подписки вовремя добавлять и убирать, чтобы не происходило утечек памяти или объекты не подписывались на событие несколько раз. Обычно это делают в методах OnEnable и OnDisable. В каждом подписчике нужно рутинно прописывать подписку/отписку и если событий набралось много, то это может вылиться в простыню кода.

Я решил запилить кастомный пакет с решением, которое поможет создавать события через удобный UI и избавит от рутины ручной подписки/отписки на них, что немного облегчит разработку.

Game Events System

Добавляйте необходимые события, выбирайте типы аргументов, группируйте события в логические "каналы" и жмите "Generate".

Сгенерируются классы по каналам со статическими событиями.
Если в качестве аргумента события необходимо указать типы, объявленные в других пакетах в проекте, то включите галочку "Include packages".

Использование

Вызов событий происходит обычным способом:

MenuChannel.OnPause?.Invoke();

Чтобы подписаться на событие, нужно добавить соответствующий атрибут к колбек-методу:

[MenuChannel.OnPause]
public void Pause()
{
// Event handling logic here
Time.timeScale = 0;
// ...
}

Вот и все, вся остальная логика по подписке/отписке сделана за вас.

Ссылка на репозиторий с пакетом:
https://github.com/IRKhabibullin/com.jarmallnick.gameeventss...

Чтобы добавить пакет к проекту нужно:
1) Скопировать ссылку на проект
2) В Unity зайти в Window -> Package Manager
3) Нажать на + и выбрать загрузку по git url

В пакет добавлена сцена с примерами использования

Буду благодарен за фидбек и идеи улучшения системы.

Unity

260 постов2.7K подписчиков

Правила сообщества

• Запрещается постить вопросы, мемы и прочую ерунду - для этого есть форумы и другие специализированные ресурсы.


• Распространение и обсуждение пиратского ПО, кейгенов, ключей и прочих пиратских файлов запрещено.


• Соблюдайте сетевой этикет. Оскорбительное поведение и мат (в том числе сокращенный или завуалированный) караются баном.


• Запрещается разводить полемики на тему "какой движок круче". Здесь мы обсуждаем только Unity.


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

Вы смотрите срез комментариев. Показать все
Автор поста оценил этот комментарий
Я решил запилить кастомный пакет с решением, которое поможет создавать события через удобный UI и избавит от рутины ручной подписки/отписки на них, что немного облегчит разработку.

Это какая-то пизда.


1. Подписка на события только в енабле/дисабле.

2. Необходимость ебаться с интерфейсом, выкликивая параметры.

3. Необходимость постоянно наследоваться от какого-то басесубскрибера.


Почему не пошел по какому-нить стандартному пути, какой-нить условный евентбас, аля евентсервис? Делаешь параметры в виде структур со всеми необходимыми данными, дженерик интерфейс подписчика с этими параметрами.

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

раскрыть ветку (4)
1
Автор поста оценил этот комментарий

Во-первых, попрошу "базу" писать не транслитом, а то мозг сломал пока пытался прочитать)


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

Подписка на события только в енабле/дисабле.
Что не так с этим, в каком сценарии это может не работать? В твоем варианте трогать execution order как-то не хочется - не надежно, банально если в проекте кто-то еще будет его трогать. И что делать если нужно не объект дизейблить, а только компонент-подписчик?

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


Необходимость постоянно наследоваться от какого-то басесубскрибера.
Тут согласен, я думаю над тем, как избавиться от этого. Можно, как ты пишешь, добавить сервис, но есть ряд причин (выведенных в основном из личного опыта) против этого.


Ну и попрошу продолжить общение не в стиле "Бъерн Страуструп отчитывает нерадивого студента", а с конструктивной критикой и с указание минусов моего подхода и плюсов твоего

раскрыть ветку (3)
1
Автор поста оценил этот комментарий
Во-первых, попрошу "базу" писать не транслитом, а то мозг сломал пока пытался прочитать)

Это дополнительная зарядка для мозга.

Что не так с этим, в каком сценарии это может не работать?

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

Да блять, ты элементарно инициализируешь на сцене неактивные объекты, или объекты с отключенными монобехавиорами, при этом тебе нужно, чтобы они получали сообщения, и все, вся концепция ломается.

В твоем варианте трогать execution order как-то не хочется - не надежно, банально если в проекте кто-то еще будет его трогать

А в большом проекте, где будет работать множество людей, ты по любому будешь трогать его. Там даже все еще интереснее. А для домашнего проекта, никто не запрещает сделать себе отдельный файлик с теми же константами скажем, и брать значение с него. У тебя перед глазами будет вся очередь, и по нажатию кнопки в среде, получаешь все объекты, которые работают по этому значению. Как ты собрался то строить системную архитектуру, боясь очереди выполнения то.

И что делать если нужно не объект дизейблить, а только компонент-подписчик?

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

Если возникает ситуация которую ты описываешь, ты просто вручную отписываешься. Я не особо понимаю, почему ты из этого сделал проблему. Две строчки на класс, это не критично. Повторяется в куче сущностей? Так вот тут ты можешь вынести это в условное BaseEntity, и с него уже наследоваться в TowerEntity (хотя тут тоже могут быть вопросы, в зависимости от подходов). И такое наследование будет выглядеть хотя бы приблизительно разумно. 

Интерфейс на то и придуман, что с ним меньше ебаться, чем писать код и он гораздо удобочитаем.

Для этого придуман хороший интерфейс, да. Плохой, нет.

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

Блять, мне как программисту, чтобы просто добавить простой евент, нужно лезть в интерфейс движка? В этом удобство? При этом работаю с ними только я, и только в коде, судя по реализации.

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

Ебать спасибо нахуй, удружил)

Тут согласен, я думаю над тем, как избавиться от этого.

Заебись. Вот вам решение, оно плохое, думаю как это исправить, только я вам об этом не скажу)

Можно, как ты пишешь, добавить сервис, но есть ряд причин (выведенных в основном из личного опыта) против этого.

Вроде этот вопрос обсосали уже тыщу раз со всех сторон, во всех возможных вариантах. Пиши, обсудим.

Ну и попрошу продолжить общение не в стиле "Бъерн Страуструп отчитывает нерадивого студента", а с конструктивной критикой и с указание минусов моего подхода и плюсов твоего

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

раскрыть ветку (2)
Автор поста оценил этот комментарий
инициализируешь на сцене неактивные объекты, или объекты с отключенными монобехавиорами, при этом тебе нужно, чтобы они получали сообщения
А что если тебе нужно подписываться в оненабле, а в ондисабле отписываться не нужно

Выглядит как антипаттерны и нарушение, скажем так, "философии" Unity. Там ведь у отключенных компонентов ни одно монобех событие не отрабатывает. Ты с таким подходом такой говнокод нагородишь, что никто не сможет его отлаживать и поддерживать.


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


А в большом проекте, где будет работать множество людей, ты по любому будешь трогать его
Конечно буду трогать, и ко всему прочему мне придется и твое решение трогать, чтобы твои монобехи-отписчики вдруг не отстали от других. А нахрена мне это надо как разрабу-пользователю чужих пакетов.
Боишься критики, нехуй показывать
В последнем твоем комменте конечно чуть больше конкретики. Но в первом было просто "я Дартаньян, а все пидарасы", а не критика)
раскрыть ветку (1)
2
Автор поста оценил этот комментарий
Выглядит как антипаттерны и нарушение, скажем так, "философии" Unity.

Хуя се, "философия юнити") По философии юнити ты должен тогда дурака не валять, а делать "геймобжект.сендмесседж" и название метода строкой пропихивать. Как задумали разработчики, по философии)

Там ведь у отключенных компонентов ни одно монобех событие не отрабатывает.

Мда, с таким знанием контекста, ты еще пытаешься умничать. Для справки, даже на отключенном компоненте срабатывает Awake, OnTriggerEnter/Exit и некоторые другие, в зависимости от настроек.

Вообще никакие события не запускаются в другом случае. Иди учить теорию)

Ты с таким подходом такой говнокод нагородишь, что никто не сможет его отлаживать и поддерживать.

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


Ну и да, довольно забавно читать это от человека, который принес нам это)

С поддержкой я как бы разобрался в предыдущем комменте, это пиздец, который программисту просто не удобен. Ты это проигнорировал, будем считать, что сказать тебе нечего по теме. Как собственно и с "личными проблемами в работе с сервисным вариантом". Пизданул чтобы казаться круче как я понимаю, но сказать по теме опять же не чего.


А что на счет отлаживания? Если мне нужно просто хотя бы в лог пускать все события (хотя бы даже без параметров, их типы/наименования), а мы их блять стартуем через "обычный способ"

Вызов событий происходит обычным способом:
MenuChannel.OnPause?.Invoke();

Как я это должен делать в твоем случае? В моем предложении это делается добавлением одной сраной строчки кода, в твоем же у нас есть 3 пути. Дикий костыль, интересный костыль, и переписывание проекта) В общем, что это? Это пиздец. На ровном месте. В элементарном примере.

Система сделана как раз для монобехов, то есть основным потребителем будет игровой UI и например MVC контроллеры объектов. Потому и привязка к жизненному циклу монобеха.

А для всего остального, ты будешь писать отдельную систему, и будешь поддерживать 2 разных кода выполняющих один и тот же функционал? Тут можно еще больше веселых интерфейсков наделать)

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

Не особо понял, что ты хотел сказать. Кто от кого должен отставать, если это ты контролируешь, и конфигурировать как нужно именно тебе все это, никто не запрещает. И когда ты берешься использовать чужой код, тебе все равно приходится поддерживать архитектуру принятую в нем. В твоем например, нужно обязательно наследоваться, а если класс у меня уже наследуется? Мне нужно прокидывать его через всех наследников? Нет. Твое предложение просто идет нахуй. Гибкость блять.

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

Но в первом было просто "я Дартаньян, а все пидарасы", а не критика)

Эээ... А кто брал тезисы из моего первого коммента, и пытался их опровергать? То бишь пытался отвечать на мою критику? Или чем ты тогда там занимался то, чудак ты человек?) Я тебе описал 3 острые проблемы, и предложил более действенное решение твоей проблемы.


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

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


Так и живем. Так и крепчаем...

Иллюстрация к комментарию
Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества