UE4_代理(Delegate)
来源:互联网 发布:ajax提交form表单json 编辑:程序博客网 时间:2024/05/16 17:31
代理(delegate)
1. 代理相当于时间调度器,他们俩的功能类似。delegate多用于虚幻C++,而事件调度器多用于蓝图。 2. delegate可以让任意类对象都可以向某些特定事件进行注册,当特定的事件发生时就可以得到通知并进行处理。 3. 使用delegate可以绑定一个成员函数到任意对象,并由被绑定的对象进行呼叫,被绑定的对象可以不知道绑定在自己身上的成员函数的类型
EventHandler(事件处理器函数)
1. Actor和Component 都采用虚函数的方式内置了一些EventHandler,比如: BeginPlay(),BeginDestroy()....等等,用复写的方式来实现。例如: virtual void NotifyActorBeginOverlap(AActor* OtherActor); virtual void NotifyActorEndOverlap(AActor* OtherActor);
创建Delegate并绑定
1. 声明 使用DECLARE_DELEGATE(FDelegateSignature)宏声明代理类型2. 类内FDelegateSignature myDelegate;声明一个以FDelegateSignature作为类型的成员变量3. 在接受通知事件的类内写一个EventHandler。例如BeginPlay()内获得分发事件的代理变量myDelegate,使用myDelegate.BindUObject()函数绑定Event Handler
执行Delegate
myDelegate->ExecuteIfBound();
取消 delegate绑定
myDelegate->unbind();
代码示例:(默认,先是.h文件,后是cpp文件)
DelegateGameMode
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/GameModeBase.h"#include "DelegateGameMode.generated.h"// 注册 //单播,只能注册一个DECLARE_DELEGATE(FStandardDelegateSignature)// 注册带有参数的DECLARE_DELEGATE_OneParam(FParamDelegateSignature,FLinearColor)// 多播DECLARE_MULTICAST_DELEGATE(FMulticastDelegateSingnature)/** * */UCLASS()class BLANKUECPP_API ADelegateGameMode : public AGameModeBase{ GENERATED_BODY()public: FStandardDelegateSignature StandardDelegate; FParamDelegateSignature ParaDelegate; FMulticastDelegateSingnature MultiDelegate;};
// Fill out your copyright notice in the Description page of Project Settings.#include "BlankUECPP.h"#include "DelegateGameMode.h"
BoomTriggerVolume
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"#include "BoomTriggerVolume.generated.h"DECLARE_EVENT(ABoomTriggerVolume,FPlayerEnteredEvent)UCLASS()class BLANKUECPP_API ABoomTriggerVolume : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties ABoomTriggerVolume();protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override; virtual void NotifyActorBeginOverlap(AActor* OtherActor) override; virtual void NotifyActorEndOverlap(AActor* OtherActor) override;public: UPROPERTY() UBoxComponent* TriggerBox; FPlayerEnteredEvent OnplayerEntered;};
// Fill out your copyright notice in the Description page of Project Settings.#include "BlankUECPP.h"#include "DelegateGameMode.h"#include "BoomTriggerVolume.h"// Sets default valuesABoomTriggerVolume::ABoomTriggerVolume(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox01")); // 设置盒子的大小 TriggerBox->SetBoxExtent(FVector(200, 200, 100));}// Called when the game starts or when spawnedvoid ABoomTriggerVolume::BeginPlay(){ Super::BeginPlay();}// Called every framevoid ABoomTriggerVolume::Tick(float DeltaTime){ Super::Tick(DeltaTime);}void ABoomTriggerVolume::NotifyActorBeginOverlap(AActor* OtherActor){ UWorld *world = GetWorld(); // 获得当前关卡的GameMode AGameModeBase* gameMode = UGameplayStatics::GetGameMode(world); // 转化成我们自己定义的GameMode,里边有我们注册的代理 ADelegateGameMode* delegateGM = Cast<ADelegateGameMode>(gameMode); if (delegateGM) { delegateGM->StandardDelegate.ExecuteIfBound(); delegateGM->ParaDelegate.ExecuteIfBound(FLinearColor(0,1,0)); // 多播代理执行 delegateGM->MultiDelegate.Broadcast(); } GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, FString::Printf(TEXT("%s Boom @@@@!"),*OtherActor->GetName())); OnplayerEntered.Broadcast();}void ABoomTriggerVolume::NotifyActorEndOverlap(AActor* OtherActor){ UWorld *world = GetWorld(); AGameModeBase* gameMode = UGameplayStatics::GetGameMode(world); ADelegateGameMode* delegateGM = Cast<ADelegateGameMode>(gameMode); if (delegateGM) { delegateGM->StandardDelegate.ExecuteIfBound(); //带参数代理执行 //delegateGM->ParaDelegate.ExecuteIfBound(FLinearColor(0, 1, 0)); // 多播代理执行 delegateGM->MultiDelegate.Broadcast(); } GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, FString::Printf(TEXT("%s Leave Boom @@@@!"),* OtherActor->GetName()));}
DelegateListener
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"#include "DelegateListener.generated.h"UCLASS()class BLANKUECPP_API ADelegateListener : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties ADelegateListener();protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override; virtual void EndPlay(EEndPlayReason::Type EndPlayReason) override;public: UFUNCTION() void SetLightColor(FLinearColor LightColor); UFUNCTION() void EnableLight(); UFUNCTION() void SetLightColorWithPayLoad(FLinearColor LightColor, bool isEnable);public: // 加载灯泡颜色 UPROPERTY() UPointLightComponent *PointLight; bool isEnable = false;};
// Fill out your copyright notice in the Description page of Project Settings.#include "BlankUECPP.h"#include "DelegateGameMode.h"#include "DelegateListener.h"// Sets default valuesADelegateListener::ADelegateListener(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; // 灯光的组件 PointLight = CreateDefaultSubobject < UPointLightComponent>(TEXT("PointLight01")); // 把灯光组件作为根组件 RootComponent = PointLight; PointLight->SetVisibility(false); PointLight->SetLightColor(FLinearColor::Red);}// Called when the game starts or when spawnedvoid ADelegateListener::BeginPlay(){ Super::BeginPlay(); UWorld *world = GetWorld(); if (world) { // 获得世界里边的所有的gamemode AGameModeBase *gm = UGameplayStatics::GetGameMode(world); // 把世界里的所有的gamemode转成我们定义的DelegateGameMode ADelegateGameMode *delegateGM = Cast<ADelegateGameMode>(gm); if (delegateGM) { delegateGM->StandardDelegate.BindUObject(this, &ADelegateListener::EnableLight);// 开关灯 // 同 一个代理绑了两次,它只对最后一次代理生效,这就是单播的意义。 delegateGM->ParaDelegate.BindUObject(this, &ADelegateListener::SetLightColor);// 设置颜色 //delegateGM->ParaDelegate.BindUObject(this, &ADelegateListener::SetLightColorWithPayLoad, isEnable); // 这个isEnable是一个默认参数,默认为false // 它会传给SetLightColorWithPayLoad这个函数 GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("StandardDelegate.BindUObject")); } }}// Called every framevoid ADelegateListener::Tick(float DeltaTime){ Super::Tick(DeltaTime);}void ADelegateListener::SetLightColorWithPayLoad(FLinearColor LightColor, bool isEnable){ PointLight->SetLightColor(LightColor); PointLight->SetVisibility(isEnable); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("SetLightColorWithPayLoad"));}void ADelegateListener::SetLightColor(FLinearColor LightColor){ PointLight->SetLightColor(LightColor); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("SetLightColor"));}void ADelegateListener::EnableLight(){ //PointLight->SetVisibility(true); PointLight->ToggleVisibility(); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("EnableLight"));}void ADelegateListener::EndPlay(EEndPlayReason::Type EndPlayReason){ Super::EndPlay(EndPlayReason); UWorld *world = GetWorld(); if (world) { AGameModeBase *gm = UGameplayStatics::GetGameMode(world); ADelegateGameMode *delegateGM = Cast<ADelegateGameMode>(gm); if (delegateGM) { delegateGM->StandardDelegate.Unbind(); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("StandardDelegate.Unbind()")); } }}
Explode 这个是爆炸的特效
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"#include "Explode.generated.h"UCLASS()class BLANKUECPP_API AExplode : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AExplode();protected: // Called when the game starts or when spawned virtual void BeginPlay() override; virtual void EndPlay(EEndPlayReason::Type EndPlayReason) override;public: // Called every frame virtual void Tick(float DeltaTime) override; void KaBoom();public: FDelegateHandle EnterVolumHandle; // 粒子组件 UPROPERTY() UParticleSystemComponent* ParticleComp; // 图标,用来指示我们的粒子效果在哪 UPROPERTY() UBillboardComponent* BillBoard;};
// Fill out your copyright notice in the Description page of Project Settings.#include "BlankUECPP.h"#include "DelegateGameMode.h"#include "Explode.h"// Sets default valuesAExplode::AExplode(){ // // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; ParticleComp = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("Particles")); BillBoard = CreateDefaultSubobject<UBillboardComponent>(TEXT("BoardBoom")); // BillBoard 作为根组件 RootComponent = BillBoard; // FAttachmentTransformRules 是一个枚举 ParticleComp->AttachToComponent(GetRootComponent(),FAttachmentTransformRules::KeepRelativeTransform); ConstructorHelpers::FObjectFinder<UTexture2D> boardAsset(TEXT("Texture2D'/Engine/EngineResources/AICON-Red.AICON-Red'")); if (boardAsset.Object) { // 用SetSprite是因为在蓝图里就是这个属性设置图片 BillBoard->SetSprite(boardAsset.Object); } ConstructorHelpers::FObjectFinder<UParticleSystem> particleAsset(TEXT("ParticleSystem'/Game/P_Explosion.P_Explosion'")); if (particleAsset.Object) { // SetTemplate 用来设置粒子效果 ParticleComp->SetTemplate(particleAsset.Object); ParticleComp->bAutoActivate = false;// 默认不播放 }}// Called when the game starts or when spawnedvoid AExplode::BeginPlay(){ Super::BeginPlay(); UWorld *world = GetWorld(); if (world) { AGameModeBase *gm = UGameplayStatics::GetGameMode(world); ADelegateGameMode *delegateGM = Cast<ADelegateGameMode>(gm); if (delegateGM) { // MultiDelegate 是在DelegateGameMode文件里边的 EnterVolumHandle=delegateGM->MultiDelegate.AddUObject(this,&AExplode::KaBoom); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("MultiDelegate.BindUObject")); } }}// Called every framevoid AExplode::Tick(float DeltaTime){ Super::Tick(DeltaTime);}void AExplode::EndPlay(EEndPlayReason::Type EndPlayReason){ Super::EndPlay(EndPlayReason); UWorld *world = GetWorld(); if (world) { AGameModeBase *gm = UGameplayStatics::GetGameMode(world); ADelegateGameMode *delegateGM = Cast<ADelegateGameMode>(gm); if (delegateGM) { // 如果不记录这个EnterVolumeHandle这个Handle的话,用RemoveAll比较合适 delegateGM->MultiDelegate.Remove(EnterVolumHandle); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("MultiDelegate.BindUObject")); } } }void AExplode::KaBoom(){ //ParticleComp->ActivateSystem(false); // 激活粒子组件 ParticleComp->ToggleActive();}
UpDownPlatform 文件
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"#include "BoomTriggerVolume.h"#include "UpDownPlatform.generated.h"UCLASS()class BLANKUECPP_API AUpDownPlatform : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AUpDownPlatform();protected: // Called when the game starts or when spawned virtual void BeginPlay() override; void Move();public: // Called every frame virtual void Tick(float DeltaTime) override; UPROPERTY(EditAnyWhere) UStaticMeshComponent* PlatformMesh;private: UPROPERTY(EditAnyWhere,Category=Destination) class ABoomTriggerVolume* TriggerVolum; // 目标位置是我们在编辑器中手动指定的位置 UPROPERTY(EditAnyWhere, Category = Destination,meta=(AllowPrivateAccess=true,MakeEditWidget=true)) FVector TargetLocation; FVector BeginLocation;};
// Fill out your copyright notice in the Description page of Project Settings.#include "BlankUECPP.h"#include "UpDownPlatform.h"// Sets default valuesAUpDownPlatform::AUpDownPlatform(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot")); PlatformMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh0")); PlatformMesh->SetupAttachment(RootComponent); ConstructorHelpers::FObjectFinder<UStaticMesh> meshAsset(TEXT("StaticMesh'/Game/SM_Platform.SM_Platform'")); if (meshAsset.Object) { PlatformMesh->SetStaticMesh(meshAsset.Object); // 设置缩放比 PlatformMesh->SetRelativeScale3D(FVector(1, 1, 0.1)); }}// Called when the game starts or when spawnedvoid AUpDownPlatform::BeginPlay(){ Super::BeginPlay(); // GetActorLocation获得当前的位置 BeginLocation = GetActorLocation(); GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Blue, TargetLocation.ToString()); //把本地坐标转成世界坐标 TargetLocation= GetActorTransform().TransformPosition(TargetLocation); GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Green, TEXT("After:")+TargetLocation.ToString()); if (TriggerVolum) { ABoomTriggerVolume *trigger = Cast<ABoomTriggerVolume>(TriggerVolum); if (trigger) { // OnPlayerEntered 是在BoomTriggerVolume注册的一个事件 trigger->OnplayerEntered.AddUObject(this, &AUpDownPlatform::Move); GEngine->AddOnScreenDebugMessage(-1,5.0f,FColor::Red,TEXT("OnPlayerEntered.AddUObject")); } }}// Called every framevoid AUpDownPlatform::Tick(float DeltaTime){ Super::Tick(DeltaTime);}void AUpDownPlatform::Move(){ // 实现来回移动功能,先记录当前的位置,判断当前位置是否是目标位置,再来回移动 FVector curLoc = GetActorLocation(); if (curLoc.Equals(TargetLocation)) { SetActorLocation(BeginLocation); } else { SetActorLocation(TargetLocation); }}
阅读全文
0 0
- UE4_代理(Delegate)
- UE4_代理示例_时钟
- delegate 代理
- C#中的代理(Delegate)
- 代理(delegate)问题
- delegate,C#,代理
- C#中的代理(Delegate)
- C#中的代理(Delegate)
- C#中的代理(Delegate)
- C#中的代理(Delegate)
- C#中的代理(Delegate)
- Delegate代理实现
- Swift-代理-delegate
- Delegate 代理步骤
- 学习代理 笔记 delegate
- delegate事件代理
- Customised delegate 自定义代理
- IOS Delegate代理实现
- Java基本数据类型在内存中的存储大小实践
- poj1390
- Mac nvm安装细节备忘
- iOS_通话时间的计算
- 7月26日云栖精选夜读:MySQL金融版线上发布会:它为什么是金融企业的首选_技术大佬、产品和神秘嘉宾本位“演绎”
- UE4_代理(Delegate)
- 教你少走点弯路
- Mysql编码之查看、修改总结
- PHP 开发者该知道的 5 个 Composer 小技巧
- Spark RDD基本操作
- 密码学——OSI安全框架(Cryptography
- 微服务:Spring Boot第一篇——什么是Spring
- python3异常使用
- 一张图看懂数据科学家、数据工程师和软件工程师之间的区别