如何在代码中创建抽象类,让蓝图扩展它,并将该蓝图返回给代码进行实例化?

How can I create an abstract class in code, let a blueprint extend it, and give that blueprint back to code to instantiate?

本文关键字:代码 返回 实例化 抽象类 创建 扩展      更新时间:2023-10-16

假设我想在代码中创建一个用于控制棋子的AI类,但我希望我的设计师能够使用蓝图修改行为以进行快速迭代。

假设我在MyProjectBaseAI.h中有这个:

#pragma once
#include "EngineMinimal.h"
#include "GameFramework/Actor.h"
#include "MyProjectBaseAI.generated.h"
UCLASS()
class MYPROJECT_API AMyProjectBaseAI : AActor
{
GENERATED_BODY()

public:
AMyProjectBaseAI(const FObjectInitializer& ObjectInitializer);
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
void SetGoalPosition(FVector pos);

virtual void DetermineGoalPosition(int32 stateData1, int32 stateData2) = 0;
private:
FVector goalPosition;
};

我想使这个类抽象,并有一个蓝图,能够实现DetermineGoalPosition(...);调用SetGoalPosition(FVector pos),具体取决于他们对AI的设计。

那么,设计人员如何在检查器中设置实现类,以便我的C++代码可以实例化它?假设我有一个类想要像这样实例化实现类(当前使用基类):

AMyProjectBaseAI* ai = World->SpawnActor<AMyProjectBaseAI>(...);

抽象类设置:

  1. 使用UCLASS中的AbstractBlueprintable说明符将类标记为抽象和可蓝图(尽管,当您从AActor或其他可蓝图类继承时,Blueprintable说明符是多余的)。

  2. UFUNCTION说明符中使用BlueprintImplementableEvent进行DetermineGoalPosition。这允许蓝图实现该功能。

另外,不要根据虚幻引擎4.8版的标准将该函数声明为虚拟函数

新增功能:从多个引擎级蓝图实现事件中删除了"虚拟"关键字,以符合新的"蓝图实现事件不应是虚拟的"标准。

  1. UFUNCTION说明符中使用BlueprintCallable属性进行SetGoalPosition。这允许从蓝图调用函数。

    #pragma once
    #include "EngineMinimal.h"
    #include "GameFramework/Actor.h"
    #include "MyProjectBaseAI.generated.h"
    UCLASS(Abstract, Blueprintable)
    class MYPROJECT_API AMyProjectBaseAI : AActor 
    {
    GENERATED_BODY()
    public:
    AMyProjectBaseAI(const FObjectInitializer& ObjectInitializer);
    virtual void BeginPlay() override;
    virtual void Tick(float DeltaSeconds) override;
    UFUNCTION(BlueprintCallable)
    void SetGoalPosition(FVector pos);
    UFUNCTION(BlueprintImplementableEvent)
    void DetermineGoalPosition(int32 stateData1, int32 stateData2);
    private:
    FVector goalPosition;
    };
    

实例化器设置

  1. 然后在类的标头中,您希望在检查器中设置实现类,使用带有EditAnywhere说明符的公共TSubclassOf<AMyProjectBaseAI>变量(如果子类应仅在编辑器中的蓝图或实例级别设置,则EditDefaultsOnlyEditInstanceOnly):

    public:
    UPROPERTY(EditAnywhere)
    TSubclassOf<AMyProjectBaseAI> AIImplementationClass;
    
  2. 然后在实例化它的地方,只需使用AIImplementationClass作为类:

    AMyProjectBaseAI* ai = World->SpawnActor<AMyProjectBaseAI>(AIImplementationClass);