LatentInfo is wrong if it's the first parameter of a Latent method

UE4.10.4

If LatentInfo is the first parameter of a latent method in a Blueprint Library it receives wrong linkage number.
Here’s an example code:

	// Header
	UFUNCTION(BlueprintCallable, Category = "Test", meta = (Latent, LatentInfo = "LatentInfo"))
	static void MyTestNode(
		FLatentActionInfo LatentInfo,
		UObject* SomeObject,
		float Delay
	);

	// CPP
void UMyBlueprintLibrary::MyTestNode(
	FLatentActionInfo LatentInfo,
	UObject* SomeObject,
	float Delay
)
{
	UE_LOG(LogTemp, Warning, TEXT("Linkage is %d"), LatentInfo.Linkage);
	FLatentActionManager& LatentActionManager = SomeObject->GetWorld()->GetLatentActionManager();
	LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FDelayAction(Delay, LatentInfo));
}

Calling that linkage number, makes this node run over and over again (though this might be a coincidence, it being just a random node id)

If LatentInfo info parameter is the last parameter of a method, it works just fine and receives a correct linkage id, that calls correct node.

I tried to investigate that bug deeper, but got lost in the VM bytecode compiler.

Hello grisevg,

I’m not quite familiar with working with latent info so you’ll have to excuse me but what is your expected result and what are you getting? If I run the function you posted, the output is -1 if it’s on BeginPlay, 50 if it’s called on tick. Unfortunately I’m not sure what I’m looking for. Haven’t seen any difference from switching around the parameters of the function.

-1 means there’s no latent info (no node was assigned to Completed output) and that’s normal.

But If you call this node in blueprint and assign PrintString node to Completed pin (http://i.imgur.com/697cNqC.png) , it will never be called, because linkage id given is wrong. But if you put LatentInfo parameter last, it will work just fine.

Both “correct” and “wrong” linkage ids are just numbers, but they are two different numbers, meaning that simply switching the argument’s position, changes which node id was passed into LatentInfo.

Ah I definitely see the difference now. Thank you for clarifying that. I will say however, through testing our latest versions before placing a bug report in, it doesn’t seem to be happening in our latest internal build. Due to this, I won’t be placing a bug report in. I will say, with the change, the print string never gets fired despite the position of the argument.

Please let me know if you have any more questions.

I have the same issue as the OP, in UE 4.15.1:
If the LatentInfo is the first parameter of the function, then the function itself is called again once the action finishes. If the LatentInfo is at any other position in the method header, it works as expected (the method after the latent action is called once the action is done).

Made me lose quite some time, thanks a lot grisevg for finding this out, I couldn’t have resolved this without your help :wink:

Hello or1on06,

Thank you for reporting this. As mentioned before, I’m not that familiar with using LatentInfo and when trying to test this again in 4.15.1, the code provided by grisevg above doesn’t compile. Could you give an example function that is giving you this issue so that I may test this?

Same problem here in 4.17. Very easy to repro. Create a new blank C++ project. Create a new C++ actor with the following code.

MyActor.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Engine/LatentActionManager.h"
#include "MyActor.generated.h"

UCLASS()
class LATENTACTIONTEST_API AMyActor : public AActor
{
	GENERATED_BODY()
	
public:	
	AMyActor();

	UFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = "LatentInfo"))
	void FixedDelay(FLatentActionInfo LatentInfo);

	UFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = "LatentInfo"))
	void Delay(float DelaySeconds, FLatentActionInfo LatentInfo);
};

MyActor.cpp

#include "MyActor.h"
#include "DelayAction.h"

AMyActor::AMyActor()
{
}

void AMyActor::FixedDelay(FLatentActionInfo LatentInfo)
{
	FLatentActionManager &LatentActionManager = GetWorld()->GetLatentActionManager();
	LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FDelayAction(2.0f, LatentInfo));
}

void AMyActor::Delay(float DelaySeconds, FLatentActionInfo LatentInfo)
{
	FLatentActionManager &LatentActionManager = GetWorld()->GetLatentActionManager();
	LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FDelayAction(DelaySeconds, LatentInfo));
}

Setup a blueprint to call both functions on an instance of MyActor, with a PrintString from the Completed node of each. Observe that the Completed node on Delay fires as expected, but that from FixedDelay does not, and instead FixedDelay itself is repeatedly called.

Hope that helps with tracking it down. Cheers.

Thank you for this repro, Laurie_Hedge. I’ve reproduced what was reported and found that there is a bug that actually covers this already. You can find that bug report here: UE-22342

Hi, after so many years, this problem still existing in 4.26.2. So I have to use the same solution: Make sure the “LatentInfo” is not the first parameter. What the heck!

This issue still exists in UE 5.0.1! When placing a breakpoint on the latent node you can see that it’s getting called in an infinite loop.