上一次修改时间:2020-09-12 01:53:57

蓝图C++混合编程

  1. 注意事项

    1)模块接口(API):对于一些需要被模块外部访问的函数和类,需要通过 *_API 的宏标记出来。每个被暴露在外的单项都会带来编译时间的额外消耗,因此请务必仅暴露出必须暴露的接口。如果外部只需要访问一个类中的某个函数,那么比起暴露整个类而言,仅暴露出这个函数能够节省出相当可观的编译时间。

    2)在最最基本的层面上,任意可以被放置到关卡中的游戏物体都是一个 Actor。所有的 Actor 都是继承于 AActor 类,该类是所有可生成的游戏对象的基类。

    3)Actor类里,PrimaryActorTick.bCanEverTick = true;// 将该Actor设置为每帧调用一次Tick()。如果您没有这个需要,可以将其关闭来改善性能。

  2. 在vc里定义一个能在编辑器下直接访问的属性

    新建一个c++的Actor类

    图片.png

    图片.png

    构造函数中设置上面两个变量的默认值

    图片.png

    图片.png

  3. 在vc里定义一个能被蓝图调用的函数

    注:UFUNCTION里的函数不支持重载;

    图片.png

    图片.png

    图片.png

  4. 将蓝图里的参数传递到C++

    图片.png

    图片.png

    图片.png

    图片.png

    图片.png

  5. name,text,string之间的相互转换

    蓝图中的类型转换

    图片.png

    图片.png

    C++中的类型转换

    图片.png

    图片.png

  6. C++里调用蓝图里的函数

    图片.png

    图片.png

    图片.png

    图片.png

    图片.png

  7. 在C++创建一个能被蓝图调用的算数节点

    图片.png

    图片.png

    图片.png

  8. 蓝图里调用C++函数

    注:只能在继承自本C++类的蓝图里调用

    图片.png

    图片.png

    图片.png

    调用时,如果函数里的参数里有结构体,该结构体在定义时需要加上BlueprintType关键字,且本函数需要有函数体

    图片.png

    图片.png

    图片.png

  9. 自定义枚举

    图片.png

    图片.png

    图片.png

    图片.png

  10. UE4实例的获取

    创建C++基础类

    图片.png

    选择gameMode,并保存关卡

    图片.png

    图片.png

    图片.png

    gameMode下需要加载的类

    图片.png

    gameMode中加载上面创建的类

    图片.png

    上图中的6个类,再加上gameInstance总共7个类,每个类文件里加一个打印函数

    图片.png

    获取到实例后的运行效果如下图

    图片.png

    代码如下

  11. // Fill out your copyright notice in the Description page of Project Settings.
    
    #include "TestActor001.h"
    #include "testvcGameModeBase.h"
    #include "PikaPlayerState.h"
    #include "PikaPawn.h"
    #include "PikaGameStateBase.h"
    #include "PikaPlayerController.h"
    #include "PikaHUD.h"
    #include "PikaGameInstance.h"
    
    
    // Sets default values
    ATestActor001::ATestActor001()
    {
         // 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;
    
    }
    
    // Called when the game starts or when spawned
    void ATestActor001::BeginPlay()
    {
        Super::BeginPlay();
        EventCurrent();
        
        //通过GetWorld来获取实例
        if (GetWorld()) 
        {
            //GameMode
            AtestvcGameModeBase *pikaqiuGameMode = Cast<AtestvcGameModeBase>(GetWorld()->GetAuthGameMode());
            if (pikaqiuGameMode)
            {
                pikaqiuGameMode->pikaPrint("pikaqiuGameMode");
            }
    
            //PikaPlayerState
            APikaPlayerState *pikaPlayerStateVar = Cast<APikaPlayerState>(GetWorld()->GetFirstPlayerController()->PlayerState);
            if (pikaPlayerStateVar)
            {
                pikaPlayerStateVar->pikaPrint("pikaPlayerState");
            }
    
            //PikaPlayerController
            APikaPlayerController *pikaPlayerControllerVar = Cast<APikaPlayerController>(GetWorld()->GetFirstPlayerController());
            if (pikaPlayerControllerVar) 
            {
                pikaPlayerControllerVar->pikaPrint("pikaPlayerController");
            }
    
            //pikaPawn
            APikaPawn *pikaPawnVar = Cast<APikaPawn>(GetWorld()->GetFirstPlayerController()->GetPawn());
            if (pikaPawnVar)
            {
                pikaPawnVar->pikaPrint("pikaPawn");
            }
    
            //pikaHUD
            APikaHUD *pikaHUDVar = Cast<APikaHUD>(GetWorld()->GetFirstPlayerController()->GetHUD());
            if (pikaHUDVar) 
            {
                pikaHUDVar->pikaPrint("pikaHUD");
            }
    
            //pikaGameStateBase
            APikaGameStateBase *pikaGameStateBaseVar = Cast<APikaGameStateBase>(GetWorld()->GetGameState());
            if (pikaGameStateBaseVar)
            {
                pikaGameStateBaseVar->pikaPrint("pikaGameStateBase");
            }
    
            //pikaGameInstance
            UPikaGameInstance *pikaGameInstanceVar = Cast<UPikaGameInstance>(GetWorld()->GetGameInstance());
            if (pikaGameInstanceVar) 
            {
                pikaGameInstanceVar->pikaPrint("pikaGameInstance");
            }
        }
    }
    
    // Called every frame
    void ATestActor001::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    
    }
    
    float ATestActor001::pikaFloat(float pika1, float pika2)
    {
        return false;
    }
  12. actor实例之间的相互获取

    从PikaActorA里获取PikaActorB和PikaActorC的实例

    创建三个c++的actor类,并为每个acotr创建一个基于本类的蓝图类

    图片.png

    图片.png

    PikaActorB和PikaActorC里各加两个打印函数

    图片.png

    图片.png

    注:GEngine需要包含Engine.h头文件;

    蓝图的加载方式里,需要在蓝图里指定要获取的实例

    图片.png

    运行效果如下:

    图片.png

    加了迭代后的效果如下:

    图片.png

    PikaActorA里的代码如下:

  13. // Fill out your copyright notice in the Description page of Project Settings.
    
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "PikaActorB.h"
    #include "PikaActorC.h"
    #include "PikaActorA.generated.h"
    
    
    UCLASS()
    class PIKAQIUTEST_API APikaActorA : public AActor
    {
        GENERATED_BODY()
        
    public:    
        // Sets default values for this actor's properties
        APikaActorA();
    
    protected:
        // Called when the game starts or when spawned
        virtual void BeginPlay() override;
    
    public:    
        // Called every frame
        virtual void Tick(float DeltaTime) override;
    
        //从pikaActorA中获取pikaActorB和pikaActorC的实例
        //方法一
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = UI)
            APikaActorB *pikaActorBvar;
    
        //方法二
        TSubclassOf<AActor> getInstanceForC;
        //APikaActorC *pikaActorCvar;
        
        //通过迭代来获取场景中的实例
        void GetInstanceFor();
    
        void pikaPrint(FString pikaStr);
        void pikaPrintSelf();
    };
    
    
    -------------------上面的PikaActorA.h文件,下面的PikaActorA.cpp文件
    
    // Fill out your copyright notice in the Description page of Project Settings.
    
    #include "PikaActorA.h"
    #include "Engine.h"
    
    
    
    // Sets default values
    APikaActorA::APikaActorA()
    {
         // 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;
    
        static ConstructorHelpers::FClassFinder<AActor> pikaActorCTemp(TEXT("/Game/MyPikaActorC"));
        getInstanceForC = pikaActorCTemp.Class;
    }
    
    // Called when the game starts or when spawned
    void APikaActorA::BeginPlay()
    {
        Super::BeginPlay();
    
        if (GetWorld()) 
        {
            //从pikaActorA中获取pikaActorB的实例,该方法需要在蓝图下指定要获取的实例
            if (pikaActorBvar)
            {
                APikaActorB *pikaActorBInstance = Cast<APikaActorB>(pikaActorBvar);
                if (pikaActorBInstance) 
                {
                    pikaActorBInstance->pikaPrintSelf();
                }
            }
    
            //从pikaActorA中获取pikaActorC的实例,需要在上面的构造函数里获取pikaActorC实例的路径
            AActor *pikaActorCvar = GetWorld()->SpawnActor<AActor>(getInstanceForC, FVector::ZeroVector, FRotator::ZeroRotator);
            if (pikaActorCvar) 
            {
                APikaActorC *pikaActorCInstance = Cast<APikaActorC>(pikaActorCvar);
                if (pikaActorCInstance)
                {
                    pikaActorCInstance->pikaPrintSelf();
                }
            }
        }
    
        //调用迭代获取实例的函数
        GetInstanceFor();
        
    }
    
    // Called every frame
    void APikaActorA::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    
    }
    
    void APikaActorA::GetInstanceFor() 
    {
        AActor *tempPointer = NULL;
        //TObjectIterator它可以获取的到我们场景里面的Object实例
        int pikaInt = 0;
        for (TObjectIterator<AActor>It;It;++It) 
        {
            tempPointer = *It;
            if (tempPointer)
            {
                APikaActorA *pikaActorAInstance = Cast<APikaActorA>(tempPointer);
                if (pikaActorAInstance)
                {
                    pikaActorAInstance->pikaPrintSelf();
                }
    
                APikaActorB *pikaActorBInstance = Cast<APikaActorB>(tempPointer);
                if (pikaActorBInstance)
                {
                    pikaActorBInstance->pikaPrintSelf();
                }
    
                APikaActorC *pikaActorCInstance = Cast<APikaActorC>(tempPointer);
                if (pikaActorCInstance)
                {
                    pikaActorCInstance->pikaPrintSelf();
                }
            }
            ++pikaInt;
        }
        pikaPrint(FString::FromInt(pikaInt));
    };
    
    void APikaActorA::pikaPrint(FString pikaStr)
    {
        if (GEngine)
        {
            GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, pikaStr);
        }
    };
    
    void APikaActorA::pikaPrintSelf()
    {
        pikaPrint("PikaActorA");
    }
  14. 写一个能被蓝图调用的C++类

    1)创建一个蓝图函数类

    图片.png