使用蓝图(Blueprint)绑定多播委托(Multicast Delegate)【UE4】【C++】

本例 (国王驾崩以后,其下的农民听到风声都四下逃窜) 将讲解 如何在 C++ 中创建一个多播委托,然后在运行时通知一组的 Actors(即广播事件给监听事件的对象们)

首先创建一个 继承自 StaticMeshActor 的类,命名为 King (国王)

King.h

// the type name of new delegate signature being created
// the type of the signature's parameter
// the name of the signature's parameter
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnKingDeathSignature, AKing*, DeadKing);	 

// 委托签名;
// OnKingDeath.Broadcast 和 Peasant::flee(函数指针) 的参数类型;
// Peasant::flee 参数名

UCLASS()
class TEST_API AKing : public AStaticMeshActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AKing();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	UFUNCTION(BlueprintCallable, Category = King)
	void Die();                        ///< 在关卡蓝图中调用,广播委托

	UPROPERTY(BlueprintAssignable)	   ///< 蓝图可以动态地为委托赋予事件
	FOnKingDeathSignature OnKingDeath; ///< 多播委托实例,在 Broadcast 之后调用该委托上的方法
	
};

注意动态多播委托的定义格式

King.cpp

// Sets default values
AKing::AKing()
{
 	// 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;
	auto MeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cone.Cone'"));
	if (MeshAsset.Object != nullptr)
	{
		GetStaticMeshComponent()->SetStaticMesh(MeshAsset.Object);
		GetStaticMeshComponent()->bGenerateOverlapEvents = true;
	}
	GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);
	
}

// Called when the game starts or when spawned
void AKing::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AKing::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

}

void AKing::Die()
{
	OnKingDeath.Broadcast(this); ///< 参数类型就是自身的指针
}

接着,我们再新建一个类 ——  Peasant,同样也是继承自 StaticMeshActor

Peasant.h

UCLASS()
class TEST_API APeasant : public AStaticMeshActor
{
	GENERATED_BODY()
public:
	APeasant();
	UFUNCTION(BlueprintCallable, category = Peasant)
	void Flee(AKing* DeadKing); // 自定义事件所绑定的函数
};
在蓝图中,我们会给委托实例  OnKingDeath 绑定 自定义事件(Custom Event),自定义事件绑定着 Peasant 类的 Flee 函数
 

Peasant.cpp

APeasant::APeasant()
{
	auto MeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
	if (MeshAsset.Object != nullptr)
	{
		GetStaticMeshComponent()->SetStaticMesh(MeshAsset.Object);
		GetStaticMeshComponent()->bGenerateOverlapEvents = true;
	}
	GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);

}

/// @note 委托上绑定的函数参数为 King 的指针,所以 Broadcast 也以该指针为参数
void APeasant::Flee(AKing* DeadKing)
{
	GEngine->AddOnScreenDebugMessage(-1, 2, FColor::Red, TEXT("Waily Waily!"));
	FVector FleeVector = GetActorLocation() - DeadKing->GetActorLocation();
	FleeVector.Normalize();
	FleeVector *= 500;
	SetActorLocation(GetActorLocation() + FleeVector);
}
这里有一个地方要 特别注意,由于 Flee 传进来的是一个 King 的指针,所以需要确保调用它的时候 King 指针仍然是有效的,即不能提前调用 King 的 Destroy 方法。

然后,我们基于  Peasant 类,创建一个 蓝图,命名为 BPPeasant

编辑蓝图类:

然后,我们就可以将 King 类 和若干 BPPeasant 实例拖动到场景中

编辑关卡蓝图

设定一个延时,来广播委托事件(Die 函数)

最后,我们就可以看到这样一个效果——在 5 秒之后, King 周围的 Peasant 都同时“远离” King。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShaderJoy

您的打赏是我继续写博客的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值