问题引入
最近在开发过程要进行死亡统计,考虑到其他的系统也会用到角色死亡的信息,所以采用多播的方式进行处理。
在角色类中定义一个多播委托,同时在该类中控制事件的发布,在其他类中进行监听。
原想通过官方文档进行学习,但是官方的相关文档打不开,又进行了百度,结果多数都是在c++定义委托,在蓝图中进行绑定,不符合我的需求。
然后看了一些博客之后,自己做了些尝试,成功的使用了。
实现
- 要有一个发布委托的类,这里是Character
- 要有一个监听委托的类,这里是GameState
- 定义的多播的方法参数要和监听的委托参数相同
相关代码如下
发布委托的类
MyCharacter.h
// 死亡时候的多播宏定义
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FDeadSignature, const ACharacter*, Character, const AController*, Killer, const AActor*, KilledBy, const FDamageEvent&, DamageEvent, const float, OverDamage);
UCLASS()
class FPS_API AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
/** 声明相应签名的委托变量 */
UPROPERTY(BlueprintAssignable)
FDeadSignature DieDelegate;
}
MyCharacter.cpp
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
// 添加监听该委托的方法
if (GetWorld())
{
const AMyGameState* const tGameState = GetWorld()->GetGameState<AMyGameState>();
/**
* 这里是之前一直没有搞明白的地方,
* 一直以为要添加的方法的地址,结果不是
* 是一个ScriptDelegate的const的引用
* 所以要在对应的监听类中定义ScriptDelegate变量
*/
DieDelegate.Add(tGameState->OnCharDieDelegate);
}
}
监听委托事件的类
MyGameState.h
UCLASS()
class FPS_API AMyGameState : public AGameState
{
GENERATED_BODY()
public:
ABaseGameState();
/** 定义一个ScriptDelegate
* 用该变量来绑定类中要监听多播委托发生的方法
*/
TScriptDelegate<FWeakObjectPtr> OnCharDieDelegate;
public:
/**
* character死亡的时候进行调用,用来监听玩家死亡的多播
* @param InChar the character that has died
*/
UFUNCTION()
void OnCharDiead(const ACharacter* InChar, const AController* InKiller, const AActor* InKilledBy, const FDamageEvent& InDamageEvent,const float InOverDamage);
}
MyGameState.cpp
ABaseGameState::ABaseGameState()
:TotalEnemyDeaths(0)
{
// 把方法绑定到委托代理身上
OnCharDieDelegate.BindUFunction(this,TEXT("OnCharDiead"));
}
补充
要想绑定到委托,要绑定的方法必须用UFUNCTION进行声明,
如果没有声明,UObject的反射系统找不到这个方法,无法进行绑定
要想把方法绑定到多播委托还可以使用以下方法
GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this,&APlayerCharacter::OnTrrigerEnter);
直接调用对应的的委托签名的AddDynamic方法