今天讲解的是自定义事件的触发(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 }
效果如下: