3.6 KiB
3.6 KiB
Latent
- 功能描述: 标明一个函数是一个延迟异步操作
- 使用位置: UFUNCTION
- 引擎模块: Blueprint
- 元数据类型: bool
- 关联项: LatentInfo, NeedsLatentFixup, LatentCallbackTarget
- 常用程度: ★★★★★
标明一个函数是一个延迟异步操作,需要配合LatentInfo来使用。
会导致在逻辑执行上Then(也叫Complete)引脚需要手动触发(引擎内部触发),且函数右上角增加时钟的图标。
测试代码:
class FMySleepAction : public FPendingLatentAction
{
public:
float TimeRemaining;
FName ExecutionFunction;
int32 OutputLink;
FWeakObjectPtr CallbackTarget;
FMySleepAction(float Duration, const FLatentActionInfo& LatentInfo)
: TimeRemaining(Duration)
, ExecutionFunction(LatentInfo.ExecutionFunction)
, OutputLink(LatentInfo.Linkage)
, CallbackTarget(LatentInfo.CallbackTarget)
{
}
virtual void UpdateOperation(FLatentResponse& Response) override
{
TimeRemaining -= Response.ElapsedTime();
Response.FinishAndTriggerIf(TimeRemaining <= 0.0f, ExecutionFunction, OutputLink, CallbackTarget);
}
};
UCLASS(Blueprintable, BlueprintType)
class INSIDER_API UMyFunction_Latent :public UBlueprintFunctionLibrary
{
public:
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, meta = (Latent, WorldContext = "WorldContextObject", LatentInfo = "LatentInfo", Duration = "5"))
static void MySleep(const UObject* WorldContextObject, float Duration, FLatentActionInfo LatentInfo)
{
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
{
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
if (LatentActionManager.FindExistingAction<FMySleepAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == NULL)
{
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FMySleepAction(Duration, LatentInfo));
}
}
}
UFUNCTION(BlueprintCallable, meta = (Latent, WorldContext = "WorldContextObject", Duration = "5"))
static void MySleep2(const UObject* WorldContextObject, float Duration, FLatentActionInfo LatentInfo);
};
蓝图效果:
MySleep可以像Delay一样正常工作。但是MySleep2因为没有标明LatentInfo,因此LatentInfo函数参数没有被蓝图系统赋值,导致无法工作。
在源码里Latent使用的非常频繁,最常见的例子:
UFUNCTION(BlueprintCallable, meta=(WorldContext="WorldContextObject", Latent = "", LatentInfo = "LatentInfo", DisplayName = "Load Stream Level (by Name)"), Category="Game")
static ENGINE_API void LoadStreamLevel(const UObject* WorldContextObject, FName LevelName, bool bMakeVisibleAfterLoad, bool bShouldBlockOnLoad, FLatentActionInfo LatentInfo);
UFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = "LatentInfo", WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Utilities")
static ENGINE_API void LoadAsset(const UObject* WorldContextObject, TSoftObjectPtr<UObject> Asset, FOnAssetLoaded OnLoaded, FLatentActionInfo LatentInfo);
UFUNCTION(BlueprintCallable, Category="Utilities|FlowControl", meta=(Latent, WorldContext="WorldContextObject", LatentInfo="LatentInfo", Duration="0.2", Keywords="sleep"))
static ENGINE_API void Delay(const UObject* WorldContextObject, float Duration, struct FLatentActionInfo LatentInfo );
关于使用Latent还是继承自UBlueprintAsyncActionBase来创建蓝图异步节点的差异,可以在网上别的文章查看。