Отличия делегатов в Unreal Engine
Делегаты в Unreal Engine - это реализация известного паттерна проектирования Observer. Клиентский класс подписывается на делегат и слушает программные события, а класс, публикующий делегат, может в свою очередь уведомлять всех клиентов, даже не зная, существуют они или нет. В целом, это делает код менее связанным.
Я решил написать эту небольшую шпаргалку, чтобы самому разобраться в отличиях между делегатами. Потому что раньше, чтобы ответить на вопрос: "Какой делегат использовать сейчас?" мне приходилось лазить по туториалам и докам, собирая всю информацию вместе.
Какой делегат использовать сейчас?
Static Delegates
Static Delegate - это самый простой делегат, он позволяет добавлять только один обработчик событий.
Допустим, каждый раз когда вы стреляете, вам надо отправлять событие. Вот так вы декларируете и объявляете делегат:
А вот так использовать его:
Статический делегат работает только с обычными классами, но если вы хотите слушать его из наследника UObject, то используйте функцию: OnFireDelegate.BindUObject
Когда использовать?
Когда вам нужен самый простой и быстрый способ обработать событие.
Static Multicast Delegates
В отличии от простого статического делегата, к Static Multicast Delegate можно добавлять несколько обработчиков событий с помощью метода AddRaw:
И код клиентского класса:
Обратите внимание, что для отправления события используется метод Broadcast. Он хорош тем, что не нужно проверять, есть ли обработчики событий у данного делегата или нет.
Когда использовать?
Когда вам нужен больше чем один обработчик.
Dynamic Delegates
Простые динамические делегаты - самые скучные из всех. Их отличие от статических в том, что их можно сериализовывать. При этом они медленнее.
Объявлять их надо так:
Важный момент: функцию-обработчик следует аннотировать макросом UFUNCTION.
А так использовать:
Когда использовать?
Когда вы имеете дело с сериализацией.
Dynamic Multicast Delegates
И наконец, самый многофункциональный делегат. Dynamic Multicast Delegates обладают характеристиками всех остальных. И это позволяет использовать их в блюпринтах.
Вот так они объявляются:
Делегат нужно аннотировать макросом UPROPERTY(BlueprintAssignable), чтобы использовать его в блюпринте:
Конечно же, такой делегат можно обрабатывать и в C++:
Так же, как и в случае с Dynamic Delegate, функцию-обработчик нужно аннотировать макросом UFUNCTION.
Когда использовать?
Когда обрабатывать событие нужно в блюпринте.
p.s. Это перевод статьи из моего англоязычного блога. Оригинал тут: