GetWorld is null in UObject classes

In my source i’m using “action” classes which inherit UObject to perform multiple actions on the character.

When calling the GetWorld() inside the action classes, it return null.



CurrentAction = NewObject<USwatAction>(this, FocusedActorAction, FName(TEXT("CharacterAction")), RF_Standalone);
CurrentAction->StartAction(TargetActor);


where CurrentAction and ActionClass are



TSubclassOf<class USwatAction> FocusedActorAction;
class USwatAction* CurrentAction;


My game crashes on calling the StartAction because the GetWorld returns null




void USwatAction::Internal_ActionStarted()
{
	auto World = GetWorld();
	if (!World)
	{
		UE_LOG(LogSwat, Error, TEXT("NO WORLD CONTEXT IN ACTION"));
	}

	TimeStarted = 0.0f; // GetWorld()->GetTimeSeconds();
	TimeActive = 0.0f;
	bIsActive = true;

	if (Duration > 0.0f)
	{
		GetWorld()->GetTimerManager().SetTimer(ActionTimer, this, &USwatAction::Internal_ActionCompleted, Duration, false);
	}

	OnActionStarted();
}


How can i get a valid world context in the my action class?

1 Like

Found the solution by looking trough the engine source

UObject::GetWorld() allways returns null



virtual class UWorld* GetWorld() const override;




class UWorld* USwatAction::GetWorld() const
{
	auto SwatCharacter = GetOuterASwatCharacter();
	if (SwatCharacter)
	{
		return SwatCharacter->GetWorld();
	}
	return nullptr;
}


1 Like

Yes, someone told me that a UObject has no World assigned to it. Other than an Actor.
You will want to pass this UObject the World of its creator. So when creating it in one
of your Actors that has a valid World, just pass it to him.

UObjects not necessarily have transform component, to get world context must be an Actor/Pawn, anything with a transform…

UObjects do not have to have a world, but if you override GetWorld so that it does have a world, you will gain access to world related functions in blueprint graphs of those UObjects! :slight_smile: Have a look at my last post here: UObject vs Actor event graphs - C++ Gameplay Programming - Unreal Engine Forums

This code is unusable :frowning:

This can happen if you create the UObject in the native constructor of its owner.

 MyInstance
      = NewObject<UMyObject>(this, FName("ObjectNameInEditor"));

or

 MyInstance
      = CreateDefaultSubobject<UMyObject>(TEXT("ObjectNameInEditor"));

both give you a failure on GetWorld(). What happens is that either these calls fails to pass the outer World to the created UObject, because the World doesn’t exist when the call to construct the UObject is made.

One way I know to guarantee a World be present is to construct the UObject during BeginPlay() of its owner using the NewObject call.

 MyInstance
      = NewObject<UMyObject>(this, FName("ObjectNameInEditor"));