[UE]多播委托的蓝图示例

2020/12 30 11:12

以下示例展示了国王被杀后,农民惊呀的场景

第一步,创建King类

  • DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam为声明委托
    • FOnKingDeathSignature为委托类型
    • AKing* 为输入参数
#pragma once
#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "King.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnKingDeathSignature, AKing*, DeadKing);

UCLASS()
class UEPROJ_API AKing : public AStaticMeshActor
{
	GENERATED_BODY()
public:
	AKing();

    UFUNCTION(BlueprintCallable, Category = King)
    void Die();

    UPROPERTY(BlueprintAssignable)
    FOnKingDeathSignature OnKingDeath;
};

#include "King.h"
#include "UObject/ConstructorHelpers.h"

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

void AKing::Die()
{
    OnKingDeath.Broadcast(this);
}

第二步,创建Peasant类

#pragma once
#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "Peasant.generated.h"

UCLASS()
class UEPROJ_API APeasant : public AStaticMeshActor
{
	GENERATED_BODY()
	
	APeasant();

    UFUNCTION(BlueprintCallable, category = Peasant)
    void Flee(AKing* DeadKing);
};

#include "Peasant.h"
#include "UObject/ConstructorHelpers.h"
#include "King.h"

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

void APeasant::Flee(AKing* DeadKing)
{
    auto actorLabel = this->GetActorLabel();
    auto msg = FString::Printf(TEXT("%s Waily!"), *actorLabel);
    GEngine->AddOnScreenDebugMessage(-1, 2, FColor::Red, msg);

    FVector FleeVector = GetActorLocation() - DeadKing->GetActorLocation();
    FleeVector.Normalize();
    FleeVector *= 500;
    SetActorLocation(GetActorLocation() + FleeVector);
}

基于Peasant创建一个蓝图类,名为:BPPeasant

然后编辑此蓝图

  • 从BeginPlay开始,接一个新节点,Get All Actors Of Class
    • 【注意】 拉节点时,要把Context Sensitive的勾去掉,否则找不到 Get All Actors Of Class
    • 在Actor Class中,选择King类

  • 最出第1个King,在Out Actors输出端,接 Get (a copy) 节点

  • 为了防止取出的节点为空,所以要添加为空判断,所以 Get All Actors Of Class 后续要添加判断语句,添加Branch节点

  • Branch要添加Condition,所以添加一个前置节点NotEqual(object)节点

  • Get(a copy)输出为 NotEqual(object)的输入,NotEqual(object)的第2个节点不选

  • GetAllActorsOfClass后续接Branch节点

  • 综上所述:以上语句为了实现 if ( GetAllAlctorsOfClass[0] != null) 的功能

  • Branch 后续添加节点:Bine Event to On King Death
    • Target 为 Get (a copy) 节点 的输出

  • Bine Event to On King Death 添加 事件, 选择 自定义事件(Add Custom Event … ),名为 KingIsDeadEvent

  • KingIsDeadEvent后续接节点 Flee,即为农夫自己执行动作

  • Flee的DeadKing为 KingIsDeadEvent 的输出节点 Dead King

然后在场景中创建一个King,四周创建几个BPPeasant。

编辑关卡蓝图

把King扔进去,2秒后,让它死,如上图所示

然后运行游戏,看表现。