今天讲解的是自定义事件的触发(Custom Event)。
在蓝图中是这个:
我们现在用代码来完成自定义事件的触发。这次我们并不使用GameModeBase类作为中介,而是就使用Trigger类充当中介,我们将其宏可以定义为EditAnywhere。
创建一个自定义事件,需要在UCLASS宏之前加上DECLARE_EVENT(类名, 自定义事件的名称,自己起即可)。
1 #pragma once
2
3 #include "CoreMinimal.h"
4 #include "GameFramework/Actor.h"
5 #include "Components\BoxComponent.h"
6 #include "MyTrigger.generated.h"
7
8
9
10 DECLARE_EVENT(AMyTrigger, FPlayerEntered)
11
12 UCLASS(Blueprintable,NotBlueprintType)
13
14 class CUSTOMEVENT_API AMyTrigger : public AActor
15 {
16 GENERATED_BODY()
17
18 public:
19 // Sets default values for this actor's properties
20 AMyTrigger();
21
22 protected:
23 // Called when the game starts or when spawned
24 virtual void BeginPlay() override;
25
26 public:
27 // Called every frame
28 virtual void Tick(float DeltaTime) override;
29
30 UPROPERTY()
31 class UBoxComponent* box;
32
33 UFUNCTION()
34 virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;
35
36 UFUNCTION()
37 virtual void NotifyActorEndOverlap(AActor* OtherActor) override;
38
39 public:
40 FPlayerEntered onPlayerEntered;
41 };
以下是Trigger类的源文件:
1 // Fill out your copyright notice in the Description page of Project Settings.
2
3
4 #include "MyTrigger.h"
5
6 // Sets default values
7 AMyTrigger::AMyTrigger()
8 {
9 // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
10 PrimaryActorTick.bCanEverTick = true;
11 box = CreateDefaultSubobject<UBoxComponent>(TEXT("box"));
12 box->InitBoxExtent(FVector(50.0f));
13 RootComponent = box;
14 }
15
16 // Called when the game starts or when spawned
17 void AMyTrigger::BeginPlay()
18 {
19 Super::BeginPlay();
20
21 }
22
23 // Called every frame
24 void AMyTrigger::Tick(float DeltaTime)
25 {
26 Super::Tick(DeltaTime);
27
28 }
29
30 void AMyTrigger::NotifyActorBeginOverlap(AActor* OtherActor)
31 {
32 onPlayerEntered.Broadcast(); //通过Broadcast()方法来通知运行其绑定的所有方法。
33 }
34
35 void AMyTrigger::NotifyActorEndOverlap(AActor* OtherActor)
36 {
37
38 }
以下是PointLight类的头文件代码:
1 // Fill out your copyright notice in the Description page of Project Settings.
2
3 #pragma once
4
5 #include "CoreMinimal.h"
6 #include "GameFramework/Actor.h"
7 #include "MyTrigger.h"
8 #include "Components\PointLightComponent.h"
9 #include "MyListener.generated.h"
10
11 UCLASS()
12 class CUSTOMEVENT_API AMyListener : public AActor
13 {
14 GENERATED_BODY()
15
16 public:
17 // Sets default values for this actor's properties
18 AMyListener();
19
20 protected:
21 // Called when the game starts or when spawned
22 virtual void BeginPlay() override;
23
24 public:
25 // Called every frame
26 virtual void Tick(float DeltaTime) override;
27
28 public:
29
30 UPROPERTY()
31 class UPointLightComponent* pointLight;
32
33 UPROPERTY(EditAnywhere)
34 AMyTrigger* eventSource; //这里引入了Trigger类的指针,并将宏设定为EditAnywhere,需要在程序运行前进行手动加载。可以修改为自动加载。
35
36 UFUNCTION()
37 void onTriggerEvent();
38
39 };
以下是PointLight类的源文件代码:
1 // Fill out your copyright notice in the Description page of Project Settings.
2
3
4 #include "MyListener.h"
5
6 // Sets default values
7 AMyListener::AMyListener()
8 {
9 // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
10 PrimaryActorTick.bCanEverTick = true;
11 pointLight = CreateDefaultSubobject<UPointLightComponent>(TEXT("pointLight"));
12 RootComponent = pointLight;
13 }
14
15 // Called when the game starts or when spawned
16 void AMyListener::BeginPlay()
17 {
18 Super::BeginPlay();
19
20 if (eventSource) {
21 eventSource->onPlayerEntered.AddUObject(this,&AMyListener::onTriggerEvent); //通过自定义事件的对象调用AddUObject函数绑定方法,而不是BindUObject方法。
22 }
23
24 }
25
26 // Called every frame
27 void AMyListener::Tick(float DeltaTime)
28 {
29 Super::Tick(DeltaTime);
30
31 }
32
33 void AMyListener::onTriggerEvent()
34 {
35 pointLight->SetLightColor(FLinearColor(FMath::RandRange(0,1), FMath::RandRange(0, 1), FMath::RandRange(0, 1)));
36 }
如果你很懒,不想手动选择,想这样自动选好。
那就这样改改:
1 TArray<AActor*> Lists;
2
3 UGameplayStatics::GetAllActorsOfClass(GetWorld(), AMyTrigger::StaticClass(), Lists);
4
5 for (int i = 0; i < Lists.Num();i++) {
6 AMyTrigger* trigger = Cast<AMyTrigger>(Lists[i]);
7 if (trigger) {
8 eventSource = trigger;
9 }
10 }
效果如下: