Мне просто нравится использовать Event Systems!

С тех пор, как я занялся разработкой игр, мне пришлось изучать массу тем, будь то 2D-графика, анимация, 3D-моделирование, программирование на C#, знакомство с движком Unity и т. д. — это просто ошеломляет. Но каким бы ошеломляющим это ни казалось, часть обучения, безусловно, является моей любимой частью, и, поскольку я пришел из программирования, я с головой погрузился в поиск необходимых тем для создания моей игры Night at the Clownville. Сегодня я хочу поделиться шаблоном проектирования программирования, обычно используемым в Unity, и я, кажется, всегда возвращаюсь к нему из-за его простоты. Введите шаблон наблюдателя.

По сути, шаблон Observer — это шаблон проектирования, который позволяет вам настроить механизм подписки для субъектов, чтобы уведомлять несколько объектов о любых событиях, происходящих с объектом, за которым они наблюдают.

Как это работает

Чтобы объяснить паттерн «наблюдатель», подумайте о следующем сценарии: предположим, вы ждете, пока ваш местный магазин пополнит запасы некоторых PS5 (я предполагаю, что вы все еще ждете своих), и вы будете ездить в магазин каждый день или около того, чтобы проверить, продукт. Хотя вы можете быть первым в любой день, кто получит свою PS5, большинство поездок кажутся бессмысленными, если вы не знаете, был ли продукт в магазине в тот день. Магазин также может отправить вам массу электронных писем, чтобы уведомить вас о других продуктах Sony, которые есть в магазине, но по сути это не те продукты, которые вам нужны. Теперь это выглядит плохо как для магазина, так и для вас как покупателя.

Что магазин может сделать сейчас, чтобы решить эту ситуацию, так это включить услугу подписки, с помощью которой покупатели могут подписаться на уведомления о доступности определенных продуктов или обычно называемые событиями. Здесь магазин будет выступать в роли издателя, а покупатели будут подписчиками. Очевидно, что покупатели, не заинтересованные в PS5, не будут подписываться на это мероприятие. В результате покупателям не нужно тратить драгоценные ресурсы на ненужные походы в магазин, а магазин может удерживать клиентов, упрощая их жизнь.

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

Проблема

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

Решение

То, что мы хотим закодировать в Unity, — это компонент игрового события, который обрабатывает передачу информации или сообщения от издателя. Помните, мы упоминали о проблеме, когда каждый издатель хочет транслировать разные типы сообщений? Один из способов справиться с этим — создать определенный узел или тип сообщения и сообщить подписчикам, что этот узел передает этот конкретный тип сообщения, и они могут подписаться на него, если захотят. Короче говоря, подумайте о том, что у YouTube есть такая структура подписки, где вы можете подписаться на видео, публикации или статьи создателя ОТДЕЛЬНО. В идеале вы бы этого не делали, но просто представьте, что это полезно при создании игр.

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

Как показано выше, метод Raise() передает событие подписчикам. Любой ответ на событие будет обрабатываться компонентом прослушивания игровых событий — Принцип единой ответственности (SRP). Оба метода RegisterListener() и UnregisterListener() делают именно то же самое, когда подписчик решает прослушать игровое событие.

Для прослушивателя игровых событий мы также хотим сделать его модульным с помощью абстрактного класса.

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

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

Пример

Давайте рассмотрим простой пример того, как я использую эту систему событий в своей игре. Предположим, я написал PlayerCoinSystem, которая обрабатывает взаимодействие с внутриигровыми монетами. Как вы можете видеть ниже, к этому компоненту прикреплены 3 события, и он может вызвать любое из 3 событий . Когда монета собрана, будет поднято конкретное событие, и вы получите идею для других событий!

С другой стороны, у меня есть прослушиватель событий типа integer, прикрепленный к компоненту пользовательского интерфейса. Он прослушивает событие OnCoinChange и соответствующим образом обновляет пользовательский интерфейс!

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

Я поделился тем, как мы можем написать наше собственное игровое событие и компонент прослушивателя игрового события в Unity, используя C#, и как их можно использовать практически в любом месте вашей игры. Хотя кодовая база Night at the Clownville в настоящее время является частной, у меня есть желание поделиться ею со всеми, кто заинтересован в том, чтобы помочь нам улучшить текущую кодовую базу. Напишите мне, если вы заинтересованы! А пока удачного кодирования!

Рекомендации