简书链接:unrealenginec不修改蓝图的情况下调用蓝图多种方式研究
文章字数:159,阅读全文大约需要1分钟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/方法原型
int32 UMyClass::Func(float param1);

UFUNCTION(BlueprintCallable)
int32 InvokeFunction(UObject* obj, FName functionName,float param1)
{
struct MyClass_Func_Parms //定义一个结构用来包装参数和返回值,就像在gen.cpp里那样
{
float param1;
int32 ReturnValue;
};
UFunction* func = obj->FindFunctionChecked(functionName);
MyClass_Func_Parms params;
params.param1=param1;
obj->ProcessEvent(func, &params);
return params.ReturnValue;
}
//使用
int r=InvokeFunction(obj,"Func",123.f);

1
2
3
4
5
6
7
8
9
/调用1
obj->ProcessEvent(func, &params);
//调用2
FFrame frame(nullptr, func, &params, nullptr, func->Children);
obj->CallFunction(frame, &params + func->ReturnValueOffset, func);
//调用3
FFrame frame(nullptr, func, &params, nullptr, func->Children);
func->Invoke(obj, frame, &params + func->ReturnValueOffset);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
template<typename... TReturns, typename... TArgs>
void InvokeFunction(UClass* objClass, UObject* obj, UFunction* func, TTuple<TReturns...>& outParams, TArgs&&... args)
{
objClass = obj != nullptr ? obj->GetClass() : objClass;
UObject* context = obj != nullptr ? obj : objClass;
uint8* outPramsBuffer = (uint8*)&outParams;

if (func->HasAnyFunctionFlags(FUNC_Native)) //quick path for c++ functions
{
TTuple<TArgs..., TReturns...> params(Forward<TArgs>(args)..., TReturns()...);
context->ProcessEvent(func, &params);
//copy back out params
for (TFieldIterator<UProperty> i(func); i; ++i)
{
UProperty* prop = *i;
if (prop->PropertyFlags & CPF_OutParm)
{
void* propBuffer = prop->ContainerPtrToValuePtr<void*>(&params);
prop->CopyCompleteValue(outPramsBuffer, propBuffer);
outPramsBuffer += prop->GetSize();
}
}
return;
}

TTuple<TArgs...> inParams(Forward<TArgs>(args)...);
void* funcPramsBuffer = (uint8*)FMemory_Alloca(func->ParmsSize);
uint8* inPramsBuffer = (uint8*)&inParams;

for (TFieldIterator<UProperty> i(func); i; ++i)
{
UProperty* prop = *i;
if (prop->GetFName().ToString().StartsWith("__"))
{
//ignore private param like __WolrdContext of function in blueprint funcion library
continue;
}
void* propBuffer = prop->ContainerPtrToValuePtr<void*>(funcPramsBuffer);
if (prop->PropertyFlags & CPF_OutParm)
{
prop->CopyCompleteValue(propBuffer, outPramsBuffer);
outPramsBuffer += prop->GetSize();
}
else if (prop->PropertyFlags & CPF_Parm)
{
prop->CopyCompleteValue(propBuffer, inPramsBuffer);
inPramsBuffer += prop->GetSize();
}
}

context->ProcessEvent(func, funcPramsBuffer); //call function
outPramsBuffer = (uint8*)&outParams; //reset to begin

//copy back out params
for (TFieldIterator<UProperty> i(func); i; ++i)
{
UProperty* prop = *i;
if (prop->PropertyFlags & CPF_OutParm)
{
void* propBuffer = prop->ContainerPtrToValuePtr<void*>(funcPramsBuffer);
prop->CopyCompleteValue(outPramsBuffer, propBuffer);
outPramsBuffer += prop->GetSize();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13

#include "OutputDevice.h"
FString cmd = FString::Printf(TEXT("TestFun HelloWorld"));
FOutputDeviceDebug device;
实例对象->CallFunctionByNameWithArguments(*cmd, device, NULL, true);
//调用通过蓝图actor调用蓝图函数
void AMyActor::CallActorFunc(AActor * c, FString funcName)
{
FOutputDeviceNull ar;
c->CallFunctionByNameWithArguments(*funcName, ar, NULL, true);
}


我这边调用天气蓝图插件测试

1
2
3
4
5
6
7
8
#include <Misc/OutputDeviceDebug.h>
FOutputDeviceDebug device;
static ConstructorHelpers::FObjectFinder<UBlueprint> UnitSelector(TEXT("Blueprint'/Game/UltraDynamicSky/Blueprints/Ultra_Dynamic_Weather.Ultra_Dynamic_Weather_C'"));
TSubclassOf<AActor> UnitSelectorClass = (UClass*)UnitSelector.Object->GeneratedClass;
TArray<AActor*> OutActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), UnitSelectorClass, OutActors);
AActor* actor = OutActors[0];
actor->CallFunctionByNameWithArguments(TEXT("TestFun HelloWorld"), device, NULL, true);

https://zhuanlan.zhihu.com/p/61042237
https://www.unrealengine.com/en-US/search?x=0&y=0&filter=All&keyword=CallFunctionByNameWithArguments
https://docs.unrealengine.com/5.0/en-US/API/Runtime/CoreUObject/UObject/UObject/CallFunctionByNameWithArguments/
https://blog.csdn.net/qq_35014708/article/details/84569831