Download

How to Enable Latent Actions in UObjects

Sep 17, 2020.Knowledge
You may have noticed that you can’t use latent actions such as Delay nodes in objects derived directly from UObject. This is because you need a valid reference to the World in order to get the Latent Action Manager and queue up a latent action. To enable latent actions in your UObject, you can override UObject::GetWorld to return a valid world pointer. An easy way to do this is to use an actor instance to construct your object and set that actor as your object’s outer. This will provide an easy path to get a reference to the world. For example:

.h:
UCLASS(BlueprintType, Blueprintable)
class MyProject_API UMyObject : public UObject
{
GENERATED_BODY()

        virtual UWorld* GetWorld() const override;

};

.cpp:
UWorld* UMyObject::GetWorld() const
{
//Return null if the called from the CDO, or if the outer is being destroyed
if (!HasAnyFlags(RF_ClassDefaultObject) && !GetOuter()->HasAnyFlags(RF_BeginDestroyed) && !GetOuter()->IsUnreachable())
{
//Try to get the world from the owning actor if we have one
AActor* Outer = GetTypedOuter();
if (Outer != nullptr)
{
return Outer->GetWorld();
}
}
//Else return null - the latent action will fail to initialize
return nullptr;
}

Note that the following code only works if an actor instance in the world is one of the outer objects of the MyObject instance. You may want to assert or log an error if you are relying on the latent action to execute.