uobject的ProcessEvent方法能执行 UFunction* 函数
UAblAbilityTask* CurrentTask = GetMutableCurrentlySelectedAbilityTask();
if (UClass* taskClass = CurrentTask->GetClass())
{
if (UFunction* DealCameraPropertyFunc = taskClass->FindFunctionByName("EditorDealCameraProperty"))
{
struct DealCameraPropertyFuncParms
{
float MyTime;
FTransform MyTransform;
};
DealCameraPropertyFuncParms MyParms;
MyParms.MyTime = 0.333f;
MyParms.MyTransform.SetLocation(FVector(5,5,5));
CurrentTask->ProcessEvent(DealCameraPropertyFunc,&MyParms);
}
}
UClass中有
查找属性
FindPropertyByName
获得属性在cdo中的地址
ContainerPtrToValuePtr
设置属性的值
SetValue_InContainer
UAblAbilityTask* CurrentTask = GetMutableCurrentlySelectedAbilityTask();
if (UClass* taskClass = CurrentTask->GetClass())
{
if (FProperty* CameraProperty = taskClass->FindPropertyByName("StartCameraProperty"))
{
if (FStructProperty* StructCameraProperty = CastField<FStructProperty>(CameraProperty))
{
if (FProperty* CustomTransform = StructCameraProperty->Struct->FindPropertyByName("CustomTransform"))
{
void* StructCameraProptertyPtr = StructCameraProperty->ContainerPtrToValuePtr<void>(CurrentTask);
CustomTransform->SetValue_InContainer(StructCameraProptertyPtr, &Res);
}
}
}
}
----------------------------------------------------------------------------------------------------
蓝图自定义数据类型和c++函数互传 ufunction customthunk
遵循发现问题和产生需求,然后解决需求和解决问题
问题和需求:
我们用蓝图的节点,其输入输出引脚,都是有固定的数据类型。就是说要用节点,必须用指定的数据类型。
有时候我们有特殊需求,比如我想调用一个节点,这个节点代表一种行为,跟数据类型无关。
比如 获得数组的长度,而不用关系数组里具体数据类型是什么。
再比如获得datatable的某一行,而不用管这一行里面的内容是什么数据类型
再比如给定section和key想从config里获得数据。
你会发现现有的蓝图节点很难满足你的需求。
总结 :我们的需求是,输入引脚的类型不定。
研究和查找资料
纵观蓝图的数据结构,boolean ,int ,float ,string ,name ,text ,array ,map ,set ,struct UObjet
能满足可变的定制化的数据类型也就是Struct
struct 能随意的添加需要的基本数据类型,这个定制的struct就是我们所需要的定制化的数据类型
最重要的一点,struct里的每个基本的数据类型,在c++端都有对应的类(uproperty相关派生类)相对应,利用蓝图数据类型和c++数据类型对等,才能进行解析数据和设置数值等功能。
接下来
如果一个引脚传入的struct里面的属性数量不定,就需要我们自己解析这个数据。
(需要了解正常的ufunction函数的解析,在xxx.generated.h和xxx.gen.cpp中了解。本人也不太懂这里就不说了)
幸好ue4留给有自定义的入口 customthunk
UFUNCTION(BlueprintCallable, CustomThunk, meta = (CustomStructureParam = "CustomStruct"),Category = "lyx" )
static void GetDataFromConfigBP(UPARAM(ref) FDummyStruct& CustomStruct,const FString& MyFileNameAndPath,const FString& MySection, const FString& MyKey );
有customthunk,就代表ue4不会自动解析GetDataFromConfigBP这个函数 需要用户手动解析,并实现这个函数。
CustomStructureParam = "CustomStruct"意思就是CustomStruct参数是 struct参数。
接下来 在.h文件中手写解析函数
DECLARE_FUNCTION(execGetDataFromConfigBP)
{
Stack.MostRecentPropertyAddress = nullptr;
Stack.MostRecentProperty = nullptr;
Stack.StepCompiledIn<UStructProperty>(NULL);
void* StructAddr = Stack.MostRecentPropertyAddress;
UStructProperty* StructProperty = Cast<UStructProperty>(Stack.MostRecentProperty);
if (!StructProperty)
{
return;
}
P_GET_PROPERTY(UStrProperty, MyFileNameAndPath);
P_GET_PROPERTY(UStrProperty, MySection);
P_GET_PROPERTY(UStrProperty, MyKey);
P_FINISH;
P_NATIVE_BEGIN;
GenericGetDataFromConfigBP(MyFileNameAndPath, MySection, MyKey,StructAddr, StructProperty);
P_NATIVE_END;
};
这一段函数是蓝图节点调用的,最重要的是
void* StructAddr = Stack.MostRecentPropertyAddress;
UStructProperty* StructProperty = Cast<UStructProperty>(Stack.MostRecentProperty);
这两句是获得了蓝图参数传过来的 自定义变量 CustomStruct的 数据地址StructAddr和对应UStructProperty*
UStructProperty相当于描述文件,描述这个struct 长度,大小和field地址等等,StructAddr是存储具体数据,相当于container
我们就是通过读取UStructProperty各种属性,通过来获得对应的具体数值,简单点UStructProperty相当于index,StructAddr相当于array。
GenericGetDataFromConfigBP(MyFileNameAndPath, MySection, MyKey,StructAddr, StructProperty);
这个函数 也是需要我们手写的具体处理数据的方法。
最重要的是对StructAddr, StructProperty解析