多播代理之前讲到过FParamMulticastDelegateSignature,实际这些名字可以自己命名,主要在宏声明上。
以前声明一个多播代理是通过DECLARE_MULTICAST_DELEGATE_OneParam(FTestDelegateSignature)完成的。
然后再声明一个FDelegateHandle对象进行中介处理。
这一次是来完成动态的多播代理。
需要改变一下宏定义:DECLARE_DYNAMIC_MULTICAST_DELEGATE(FtestdelegateSignature,参数类型,参数名)
参数名可以随便写。
这次完成一个动态多播代理——国际象棋游戏。让其他的棋子远离国王。
首先来构建国王类,在C++中创建一个StaticMeshActor类(他是ACTOR的子类)。
头文件及源文件如下:
1 // Fill out your copyright notice in the Description page of Project Settings.
2
3 #pragma once
4
5 #include "CoreMinimal.h"
6 #include "Engine/StaticMeshActor.h"
7 #include "UObject/ConstructorHelpers.h"
8 #include "King.generated.h"
9
10 /**
11 *
12 */
13
14 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FKingSignature,AKing*,myKing);
15
16 UCLASS()
17 class MYPROJECT13_API AKing : public AStaticMeshActor
18 {
19 GENERATED_BODY()
20
21 public:
22 AKing();
23
24 UFUNCTION(BlueprintCallable, Category = "King | Properties")
25 void Die();
26
27 UPROPERTY(BlueprintAssignable, Category = "King | Properties") //动态代理就是不在代码中去设置绑定了,交由蓝图去设置,通过BlueprintAssignable关键字去设置UFUNCTION的宏即可
28 FKingSignature mySig;
29 };
30
31
32 // Fill out your copyright notice in the Description page of Project Settings.
33
34
35 #include "King.h"
36 #include "Components\StaticMeshComponent.h"
37
38 AKing::AKing() {
39 PrimaryActorTick.bCanEverTick = true;
40 UStaticMeshComponent* myStaticMesh = GetStaticMeshComponent();
41 auto mesh = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cone.Cone'"));
42
43 if (mesh.Succeeded()) {
44 myStaticMesh->SetStaticMesh(mesh.Object);
45 myStaticMesh->SetGenerateOverlapEvents(true);
46 }
47 myStaticMesh->SetMobility(EComponentMobility::Movable);
48 }
49 //当国王死了就执行代理广播。因为是带参数的,且参数类型是KING,所以这里传入this指针
50 void AKing::Die()
51 {
52 mySig.Broadcast(this);
53 }
当国王死了之后会执行广播,这个广播绑定到了那个函数上了吗,没有,至少目前没有。不着急,先完成棋子的内容。
头文件及源文件代码如下:
1 // Fill out your copyright notice in the Description page of Project Settings.
2
3 #pragma once
4
5 #include "CoreMinimal.h"
6 #include "Engine/StaticMeshActor.h"
7 #include "King.h"
8 #include "UObject/ConstructorHelpers.h"
9 #include "Peasant.generated.h"
10
11
13 */
14 UCLASS()
15 class MYPROJECT13_API APeasant : public AStaticMeshActor
16 {
17 GENERATED_BODY()
18 public:
19 APeasant();
20 UFUNCTION(BlueprintCallable, Category = "Peasant")
21 void Flee(AKing* DeadKing);
22 };
23
24
25
26 // Fill out your copyright notice in the Description page of Project Settings.
27
28
29 #include "Peasant.h"
30 #include "Components\StaticMeshComponent.h"
31 #include "Engine.h"
32
33 APeasant::APeasant() {
34 PrimaryActorTick.bCanEverTick = true;
35 UStaticMeshComponent* myStaticMesh = GetStaticMeshComponent();
36 auto mesh = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
37
38 if (mesh.Succeeded()) {
39 myStaticMesh->SetStaticMesh(mesh.Object);
40 }
41 myStaticMesh->SetGenerateOverlapEvents(true);
42 myStaticMesh->SetMobility(EComponentMobility::Movable);
43 }
44
45 void APeasant::Flee(AKing* DeadKing)
46 {
47 GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, TEXT("Waily waily!"));
48 FVector FleeVector = GetActorLocation() - DeadKing->GetActorLocation();
49 FleeVector.Normalize();
50 FleeVector *= 500;
51 SetActorLocation(GetActorLocation() + FleeVector);
52 }
最主要的就是Flee方法,当国王执行了Die方法后,触发动态代理执行。动态代理执行时候,执行的就是将在蓝图中绑定的Flee方法。
创建棋子的蓝图,并如下编辑
在世界蓝图中执行KING类的Die方法,以触发执行广播:
效果如下:
这样就并没有在C++中进行了方法的绑定,而是在蓝图中进行了绑定并执行了,这就是带参数的动态多播绑定。