1. 程式人生 > >使用藍圖(Blueprint)繫結多播委託(Multicast Delegate)【UE4】【C++】

使用藍圖(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);

}
// 委託上繫結的函式引數為 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。