在(二十六)中的动态多播代理我并不是很喜欢,想改成就在C++中完成的方式。
所以这节我们活学活用,将(二十六)中的动态多播代理改成带一个参数的多播代理。
要知道的是,带参数的多播代理是可以带参数的,哪怕只代理一个。
只要是用到多播,就是AddUObject和Broadcast。
KING文件没变,只是修改了宏定义。
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 DECLARE_MULTICAST_DELEGATE_OneParam(FMyTESTSignature,AKing*)
16
17 UCLASS()
18 class MYPROJECT13_API AKing : public AStaticMeshActor
19 {
20 GENERATED_BODY()
21
22 public:
23 AKing();
24
25 UFUNCTION(BlueprintCallable, Category = "King | Properties")
26 void Die();
27
28 //UPROPERTY(BlueprintAssignable)
29 FMyTESTSignature mySig;
30 };
31
32
33
34 // Fill out your copyright notice in the Description page of Project Settings.
35
36
37 #include "King.h"
38 #include "Components\StaticMeshComponent.h"
39
40 AKing::AKing() {
41 PrimaryActorTick.bCanEverTick = true;
42 UStaticMeshComponent* myStaticMesh = GetStaticMeshComponent();
43 auto mesh = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cone.Cone'"));
44
45 if (mesh.Succeeded()) {
46 myStaticMesh->SetStaticMesh(mesh.Object);
47 myStaticMesh->SetGenerateOverlapEvents(true);
48 }
49 myStaticMesh->SetMobility(EComponentMobility::Movable);
50 }
51
52 void AKing::Die()
53 {
54 mySig.Broadcast(this);//因为绑定的方法有一个参数,且参数是KING类型,所以这里执行时候,要为绑定的方法传入参数,这里传入this指针。
55 }
再看Peasant类
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 /**
12 *
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 virtual void BeginPlay() override;
24
25 UPROPERTY(EditAnywhere,BlueprintReadWrite)
26 AKing* myKing;
27
28 private:
29 TArray<AActor*> actorlist;
30 };
31
32
33
34 // Fill out your copyright notice in the Description page of Project Settings.
35
36
37 #include "Peasant.h"
38 #include "Components\StaticMeshComponent.h"
39 #include "Kismet\GameplayStatics.h"
40 #include "Engine.h"
41
42 APeasant::APeasant() {
43 PrimaryActorTick.bCanEverTick = true;
44 UStaticMeshComponent* myStaticMesh = GetStaticMeshComponent();
45 auto mesh = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
46
47 if (mesh.Succeeded()) {
48 myStaticMesh->SetStaticMesh(mesh.Object);
49 }
50 myStaticMesh->SetGenerateOverlapEvents(true);
51 myStaticMesh->SetMobility(EComponentMobility::Movable);
52 }
53
54 void APeasant::BeginPlay() {
55
56 UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass(), actorlist);
57
58 for (int i = 0; i < actorlist.Num();i++) {
59 myKing = Cast<AKing>(actorlist[i]);
60 if (myKing) {
61 myKing->mySig.AddUObject(this, &APeasant::Flee);
62 }
63 }
64 }
65
66
67 void APeasant::Flee(AKing* DeadKing)
68 {
69 GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, TEXT("Waily waily!"));
70 FVector FleeVector = GetActorLocation() - DeadKing->GetActorLocation();
71 FleeVector.Normalize();
72 FleeVector *= 500;
73 SetActorLocation(GetActorLocation() + FleeVector);
74 }
效果一样:
我还尝试了EVENT和DELEGATE:
//DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FKingSignature,AKing*,myKing);
//DECLARE_MULTICAST_DELEGATE_OneParam(FMyTESTSignature,AKing*)
//DECLARE_EVENT_OneParam(AKing, FMyTESTSignature,AKing*)
DECLARE_DELEGATE_OneParam(FMyTESTSignature,AKing*)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams()这种形式的代理,在绑定函数的时候,使用FScriptDelegate做代理,然后通过Add方法进行传入,使用Broadcast进行传播
DECLARE_MULTICAST_DELEGATE_OneParam()则还是使用AddUObject和Broadcast
记得选择带参数的宏定义,都是可以正常使用的。