Access to UWorld or AActor specific BP nodes from blueprints of other types: Component, Object, …

First of all, as with all my recent Feature Requests, I would like to say “thank you” to Epic Games and the Unreal Engine team for providing me and others with such a great tool, as well as its source. I hope my feedback can help improve it.

There are several very inconvenient limitations to the availability of Blueprint nodes, that have no reason not to be available. For example:

  • It is impossible to call nodes that require a world context, like “Spawn Actor from Class” or “Create Widget” from blueprints of UObject type.
  • It is impossible to call nodes that Add Component of some class (such as Add Static Mesh Component) from blueprints that aren’t AActor type.

For the first example, “Spawn Actor from Class” doesn’t have a “target” input, it implicitly calls the spawn on the World of whatever is executing the node akin to [FONT=Courier New]Self->GetWorld()->SpawnActor(…), instead of [FONT=Courier New]target->GetWorld()->SpawnActor(…). If there is a valid reference to something with a World Context, like an AActor, in the UObject, it should be possible for the UObject to request the AActor to execute the spawn. Same goes for CreateWidget node. And it is indeeed possible with an inconvenient workaround:

The only workaround I found, is to create a wrapper function in some custom class that has a world context.

In the example image below, an AActor BP called SomeActor has a function called “Spawn Some Other Actor Wrapper”. The input of the wrapper function is connected to a “Spawn Actor from Class”, output returns a referece to the spawned actor. A UObject BP called SomeObject calls this, sucessfully spawning an actor and getting the reference to it.

Of course, that’s very inconvenient and not flexible at all, as you have to manually create a wrapper function in SomeActor for any Actor class that you want to spawn, and then UObject BPs can only spawn actors if they have a reference to something inheriting from SomeActor.

See here - image 1 is no spawn node available in SomeObject class. Image 2 is wrapper function in SomeActor class. Image 3 is we get the result we need, in a very inconvenient way.

](filedata/fetch?id=1816803&d=1601389484)

**The second example **is the issue with the “Add ___ Component” nodes. There, the target pin exists, but for some reason, the node itself doens’t appear outisde of AActor node graphs. Of course, it makes sense that only actors should be able to create components on themselves, as the [FONT=Courier New]CreateDefaultSubobject C++ function for components can only be called by AActor.

What doesn’t make sense though, is that these nodes *only *appear in Actor BPs. So, any Actor can make any other Actor create a component on itself, but nothing else can - not ActorComponents, not Objects, not UserWidgets etc.

It feels like these nodes should appear from anything that has a reference to any Actor - just drag it out from the reference, that’s it.

See here: Image 1 is SomeActor asking SomeOtherActor to add a static mesh component - ALL GOOD, the node shows up, and any actor can be connected to the Target node. Image 2 is SomeComponent asking SomeOtherActor to do the same - NOTHING. Why not? There is a valid actor reference, and the node has a “target” input, as seen in image 1, but because this is a ActorComponent BP, the node can’t be placed.

Like the first example, it’s again possible to create boiler plate wrapper functions in some custom Actor class, which only call the “add component” node and return the reference. And again, it’s very inconvenient for the same reasons.

(I won’t make example images for the boiler plate “add component” functions, I assume the reader gets the point by now).

**Would Unreal developers please consider making this possible, as it makes perfect logical sense, and is indeed possible to do equivalent operations already, either ****in C++ or with weird loopholes like wrapper functions.

There are a lot of BP or partly-BP projects that need this flexibility.**

There is actually a good reason for that. By default, UObjects do not belong to any world, so it is not possible to call functions which operate on some world context. You can imagine standard UObjects as something in memory what does not really exists in the world. Actors exist in the world, so world context is available for them.

If you want to have access to world function from UObject, you need to implement GetWorld() getter for that object in C++.

.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<AActor>();
if (Outer != nullptr)
{
return Outer->GetWorld();
}
}
//Else return null - the latent action will fail to initialize
return nullptr;
}


This will give you access to all functions, just like in the actor. It requires your object Outer to be an Actor.

But I agree that it would be nice to have this accessible from BP.

I don’t think it can help as the problem here is that bunch of nodes like spawn are not accessible when searched for in object derived blueprint. There is just no way how to get World context dependant functions like SpawnActor accessible in blueprint if you don’t override GetWorld() in C++.

What usually happens is that if Unreal knows that current blueprint belongs to a World (like Actor does), it will hide WorldContextObject pin and set it to Self. If your blueprint does not belong to a World, it can not figure out what WorldContextObject should be set to, so it shows WorldContextObject for you to set it manually.

I would definitely expect functions like SpawnActor() to be searchable even in object derived classes by default, just with WorldContextObject pin visible. Sadly, in Object derived classes It does not list these (even if you disable Context Sensitive search) and you need to override GetWorld() to be able to find these. Same for things like Delay, as TimerManager lives in World. WorldContextObject is definitely something what could behave less shady and be better documented, altough when you get it, concept behind it is quite simple.

Some blueprint nodes can be also misconfigured and show WorldContextObject pin always.

Solution to accessing world context dependant functions in BP can be quite easy to implement by Epic or even at project/plugin level. You will need to create C++ class like UObject_Blueprint, override there GetWorld() and base your blueprints on this class.

I understand this, although thanks for taking the time to explain it. As I said, the thing I’m asking for is being able to call UWorld functions from AActors and other entities like GameModes, just in other node graphs.
That’s why in my original post, I mention in the first paragraph “For the first example, there’s no real reason for those nodes to be unavailable if there is a valid reference to something with a World Context in the UObject.” It can be the Outer, it can also be any reference to any valid Actor/GameMode/GameInstance/etc.

In essence, I’m asking for the SpawnActor node to have a “target” input to tell it whoever is calling the spawn.

I’m not asking the UObject to be able to do somthing equivalent to a C++ “Self->SpawnActor(…)”. I’m asking it to be able to do “SomeActorReference->SpawnActor(…)”, using the world context of the Actor that SomeActorReference is referring to. In this case, it’s the actor doing the call to its UWorld.

It is already perfectly possible in C++, as your code for example illustrates, and even possible in BP in a very very inconvenient way, as my wrapper workaround illustrates. It doesn’t go against the architecture and framework that Worlds and Actors etc exist in. The issue isn’t the technical possibiltiy to do this, it’s simply the existence of a node to do this. And apart from the UWorld issue entirely, is the possibility to create components in non-Actor BPs. Like calling SomeActorReference->CreateDefaultSubobject<Whatever>, which again, is possible and isn’t against any structural architecture of UE, just for some reason not possible in BPs.

Thanks for the link, but it’s a different issue.

One thing I noticed about the “Add __ Component” nodes, is that there’s a custom node auto-generated by the engine for each ActorComponent class. So it’s different from the “Spawn Actor” or “Create Widget” or “Construct Object”, because it doesn’t have a class-type input. Instead, there’s a different node for each class, something like the auto-generated “Switch on Enum” or “Cast to” nodes.

The one thing I thought might be possible is to write a custom K2Node for SpawnActor, which would be callable anywhere and just have a “Target” input for anything that has GetWorld() implemented. But of course that’s not an easy task at all, since there’s close to 0 documentation for K2Nodes, and among the ones found in the editor, SpawnActor is one of the most complicated ones, as it generates input pins based on the names and type of the UProperties of a given Actor class. So I think that might turn out to be a way bigger task to undertake.

Same for the “Add Component” node, creating one that could replace the engine default would probably not be easy at all, especially because the current ones are auto-generated. If the Unreal devs chose not to make the node with a class input pin, it’s probably very hard due to some specifics of the engine.

I would love for someone from the staff, or maybe someone familiar with the internals of the engine a little more than me to explain why that’s the case.

That might help to understand why that limitation to create Components, and maybe also the limitation for the UWorld nodes like SpawnActor and CreateWidgets, exists at all in the first place.

Update: I edited the original post now, to make it more easily readable and clear. I realize the original post was a little bit complicated in it language and explanation. Should be easy to understand what the request is for now.

This is pefect! My object now has access to a bunch of world related nodes that it didn’t have before. Although for re-use I created a base UWorldObject that any implementation could extend. Not sure why ue couldn’t do this in UObject, but hey. Might be a performance thing, maybe not every UObject needs world access. But I don’t see why UWorldObject (see below) couldn’t be part of the engine.

Header:



#pragma once

#include "UObject/Object.h"
#include "WorldObject.generated.h"

class UWorld;

UCLASS(BlueprintType)
class MyProject_API UWorldObject : public UObject
{
GENERATED_BODY()

public:

virtual UWorld* GetWorld() const override;
};


CPP:



#include "WorldObject.h"
#include "GameFramework/Actor.h"

UWorld* UWorldObject::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<AActor>();
if (Outer != nullptr)
{
return Outer->GetWorld();
}
}

//Else return null - the latent action will fail to initialize
return nullptr;
}


Implementation:



UCLASS(Abstract, BlueprintType)
class MyProject_API UMyObject: public UWorldObject
{
GENERATED_BODY()

public:
....
}


2 Likes