动态绑定函数的几种实现方法(二)
一、FScriptDelegte
该方法可以正常传递引用
其本质为封装了方法三:UFUNCTION
1、在SrcActor中创建两个函数
声明时需要添加UFUNCTION()
void ASrcActor::TestFunOne()
{
Helper::Debug(FString("TestFunOne"));
}
void ASrcActor::TestFunTwo(FString name, int32 & interger)
{
Helper::Debug(FString("TestFunTwo: ") + name + FString(" ") + FString::FromInt(interger));
interger = 2;
}
2、在DelActor中绑定对应函数
void ADecActor::GetSrcActor()
{
TArray<AActor*> SrcArray;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ASrcActor::StaticClass(), SrcArray);
if (SrcArray.Num()>0)
{
//获取对象
SrcActor = Cast<ASrcActor>(SrcArray[0]);
SrcObj = (UObject*)SrcActor;
//绑定并执行函数
RunFun_ScriptDele();
}
}
void ADecActor::GetSrcActor()
{
TArray<AActor*> SrcArray;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ASrcActor::StaticClass(), SrcArray);
if (SrcArray.Num()>0)
{
//获取对象
SrcActor = Cast<ASrcActor>(SrcArray[0]);
SrcObj = (UObject*)SrcActor;
//修改值
//ChangeUProperty();
//绑定并执行函数
RunFun_ScriptDele();
}
}
void ADecActor::RunFun_ScriptDele()
{
//无参数
FScriptDelegate FunDeleOne;
//绑定函数
FunDeleOne.BindUFunction(SrcObj, FName("TestFunOne"));
//执行函数
FunDeleOne.ProcessDelegate<UObject>(nullptr);
//有参数
FScriptDelegate FunDeleTwo;
FunDeleTwo.BindUFunction(SrcObj, FName("TestFunTwo"));
//定义参数
struct
{
FString Name = "FunParam";
int32 count = 1;
} FunParam;
//执行函数
FunDeleTwo.ProcessDelegate<UObject>(&FunParam);
}
3、执行结果
此时,传入的变量被修改了
二、TBaseDelegate
函数参数不允许为引用
1、在SrcActor定义测试函数
bool ASrcActor::TestFunThree(FString name, int32 interger)
{
Helper::Debug(FString("TestFunThree: ") + name + FString(" ") + FString::FromInt(interger));
return true;
}
2、在DecActor绑定
void ADecActor::RunFun_TBaseDele()
{
TBaseDelegate<bool, FString, int32> FunDele =
TBaseDelegate<bool, FString, int32>::CreateUFunction(SrcObj, "TestFunThree");
bool Result = FunDele.Execute(FString("Yes"), 999);
Helper::Debug(Result ? " True" : " False");
}
3、结果
三、UFUNCTION
可以传递引用,且可以获取返回值
如果要传指针的话只能传继承自UObject对象的指针
1、在SrcActor定义测试函数
int32 ASrcActor::TestFunFour(FString name, int32 & interger)
{
Helper::Debug(FString("TestFunFour: ") + name + FString(" ") + FString::FromInt(interger));
interger = 666;
return 555;
}
2、在DelActor中调用函数
void ADecActor::RunFun_UFUNC()
{
UFunction *FunRef = SrcObj->FindFunction(FName("TestFunFour"));
if (FunRef)
{
struct
{
FString Name = "FunParam";
int32 count = 111;
} FunParam;
SrcObj->ProcessEvent(FunRef, &FunParam);
//获取返回值
uint8* RetAddr = (uint8*)&FunParam + FunRef->ReturnValueOffset;
int32* ReAddr = (int32*)RetAddr;
Helper::Debug(FString("return:") + FString::FromInt(*ReAddr));
}
}