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

时间:2019-06-21 17:04:30

标签: c++ abstract-class unreal-engine4 unreal-blueprint

假设我想在代码中创建一个用于控制典当的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 个答案:

答案 0 :(得分:1)

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

  2. BlueprintImplementableEvent说明符中将UFUNCTION用于DetermineGoalPosition。这使蓝图可以实现该功能。

    此外,自ver 4.8起,按照虚幻的标准,不要将函数声明为虚拟

      

    新功能:从多个引擎级BlueprintImplementableEvents中删除了“虚拟”关键字,以符合新的“ BlueprintImplementableEvents不应为虚拟”标准。

  3. BlueprintCallable说明符中将UFUNCTION属性用于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;
    };
    
  4. 然后在您要在检查器中设置实现类的类的标题中,使用带有TSubclassOf<AMyProjectBaseAI>指定符的公共EditAnywhere变量:

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

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