BlueprintImplementableEvent用于实现C++调蓝图(声明在C++,实现在蓝图)
BlueprintNativeEvent除了实现C++调用蓝图外,当蓝图没有override时,会调用一个C++本地方法,本地方法为 声明的函数名+_Implementation,这个函数的声明在classtype.generated.h中由UHT自动生成
//在classtype.cpp中实现,声明在classtype.generated.h中
void FuncBPNative_Implementation(){ }
这样就可以实现一次调用,两个实现(c++实现,蓝图实现)
BlueprintNativeEvent还有一个比较有用的用法,是C++实现可以是virual,具体用法如下:
//C++实现,蓝图调用
UFUNCTION(BlueprintCallable,Category="LowLevel")
void FuncBPCallable(int a );
//C++实现默认版本,蓝图可override实现
UFUNCTION(BlueprintNativeEvent, Category="LowLevel")
void FuncBPnative();
//C++不实现,蓝图实现.主要用于C++调用蓝图
UFUNCTION(BlueprintImplementableEvent, Category="LowLevel")
void FuncBPImplement();
Tips:UFUNCTION(BlueprintImplementableEvent)
的函数我们只在 MyActor.h 中进行声明但没有实现,还有 UFUNCTION(BlueprintNativeEvent)
的函数我们在 MyActor.cpp 中实现的是 _Implementation
版本的函数,原版也没有去实现,可以肯定的是这两个函数必须要有实现,不然链接是过不了的,那么它们的实现在哪里?既然我们没有手动实现,那么肯定是 UHT 帮我们给做了,它们的原版实现就在 MyActor.gen.cpp 中,UHT为我们生成了一些函数的默认实现,如ImplementableFunc何NativeFunc,还有接口里的函数,所以我们不应该在C++里再重复实现(写了也会报错)。它们的内部实现也都是通过ProcessEvent来调用蓝图中的版本,或者调用C++里的_Implementation默认版本实现。
static FName NAME_AMyActor_FuncBPImplement = FName(TEXT("FuncBPImplement"));
void AMyActor::FuncBPImplement()
{
ProcessEvent(FindFunctionChecked(NAME_AMyActor_FuncBPImplement),NULL);
}
static FName NAME_AMyActor_FuncBPNative = FName(TEXT("FuncBPNative"));
void AMyActor::FuncBPNative()
{
ProcessEvent(FindFunctionChecked(NAME_AMyActor_FuncBPNative),NULL);
}
所以,当我们在 C++ 中调用这两个函数时,其实就是会进到这里,然后在通过 FindFunctionChecked
去寻找蓝图中的函数,通过蓝图虚拟机进入到蓝图的函数中,用一张表来总结这些函数标记,