简书链接: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, ¶ms);     return params.ReturnValue; } //使用 int r=InvokeFunction(obj,"Func",123.f);
 
   | 
 
1 2 3 4 5 6 7 8 9
   | /调用1 obj->ProcessEvent(func, ¶ms); //调用2 FFrame frame(nullptr, func, ¶ms, nullptr, func->Children); obj->CallFunction(frame, ¶ms + func->ReturnValueOffset, func); //调用3 FFrame frame(nullptr, func, ¶ms, nullptr, func->Children); func->Invoke(obj, frame, ¶ms + 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, ¶ms);         //copy back out params         for (TFieldIterator<UProperty> i(func); i; ++i)         {             UProperty* prop = *i;             if (prop->PropertyFlags & CPF_OutParm)             {                 void* propBuffer = prop->ContainerPtrToValuePtr<void*>(¶ms);                 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