Can you use a Blueprint Function Library in an Object Class

From what I can tell, I can call functions that are inside my Blueprint Function Library from a object class blueprint, is there something special I need to do / add in order to reference the library, or is this just not allowed?

4 Likes

Have the same problem. Blueprints inherited from Object class can’t access any functions from Function Library.

4 Likes

Bump! Trying to do the same thing Frustrated.

i just found this problem too. cant access a function inside my blueprint function library from a object class blueprint

Have the same Problem

2 Likes

I think, everyone should vote for this topic. Maybe Epic will pay some attention to it.

3 Likes

I’ve found that the only way to do it is to copy and paste the function library node from another blueprint. However, it is quite awkward even doing that, because sometimes it will say “Conflicting nodes substituted during paste!” and not paste anything.

However, as long as I place the node somewhere inside of any function library with no nodes connected, then copy it, and then paste inside of the Object blueprint, it will work.

The one issue is that on compiling the Object blueprint, you will get a warning that using that node in an Object is “unsafe”, but as far as I can tell you can just ignore it.

I have no idea why it’s “unsafe” and why it’s so convoluted to do it at all, but in the absence of anyone in-the-know commenting with an actual reason, I am inclined to believe it’s just fine, because I’ve as yet encountered no side effects of this “unsafe” implementation.

1 Like

I realize this question is a year old, but it is still the top result on Google for this issue and still had no actual answer posted.

1 Like

I believe this is due to this issue:

1 Like

This is an unfortunate limitation, I don’t understand why it exists. I guess the alternative is, use an actor component or something instead.

This is one of many undocumented limitations of blueprints.

4 Likes

Bump! Still an issue in 4.19. Now that epic got “out of the way” for Niagara users, lets hope we are next.

You spoiled kids, back in my day subclassing UObject wasn’t even a thing…everything had to be an AActor. Now that I am finally able to manually recreate my Soundmanager where it belongs (because reparenting is another well limited feature) I cannot use any of my libraries anymore. Small loses :frowning:

1 Like

This is a very strange limitation and very unconvinient.

Lets say i just want to return a constant variable from BlueprintLibrary
and use it from Child of UObjectClass.
And I Can Not do that simple thing.

I just barely see any limitation for not doing this.
Could Epic say How to avoid this or what implementing this will not be done?

I can not use Polymorfism concept becouse of that…

2 Likes

Ok.

Solution founded.

In Short than ever you need functions that can use BlueprintFunctionLibraries or even SpawnActorOfClass from Anythere use variable of UserWidgetClassChild.

Example of selectable polimorfism:

  1. Create child of UserWidgetClass call it something like SpecificFunctionCallerBase_ActionName (You than can create childs and override functions there).
  2. In your UObjectChild create variable of that type.
  3. Select one of created FunctionCallers in that variable.
  4. Now you can just construct (or create widget ) from that variable and call any function you need from anythere.

Enjoy. Vote.

By the way Epic i hope you will give us the ability to use FunctionLibraryFunctions from UObjectChildClass directly.

Edit.
You can even use WidgetClass( it looks basicly as ordinary object) as parent than construct object of that type and call function but i dont know is this save or unsave to use.

1 Like

This is indeed the problem. There’s a check to see if a blueprint library function requires a world context:

// enforce WorldContext restrictions
const bool bInsideBpFuncLibrary = Blueprint && (BPTYPE_FunctionLibrary == Blueprint->BlueprintType);
if (!bInsideBpFuncLibrary && 
    Function->HasMetaData(FBlueprintMetadata::MD_WorldContext) && 
    !Function->HasMetaData(FBlueprintMetadata::MD_CallableWithoutWorldContext))
{
    check(Blueprint);
    UClass* ParentClass = Blueprint->ParentClass;
    check(ParentClass);
    if (ParentClass && !FBlueprintEditorUtils::ImplementsGetWorld(Blueprint) && !ParentClass->HasMetaDataHierarchical(FBlueprintMetadata::MD_ShowWorldContextPin))
    {
        MessageLog.Warning(*LOCTEXT("FunctionUnsafeInContext", "Function '@@' is unsafe to call from blueprints of class '@@'.").ToString(), this, ParentClass);
     }
}

You can satisfy the check and remove the warning by overriding UObject::GetWorld() in your UObject derived class (I did this in the parent C++ class in my case. I’m not sure if it works if you add that function to your blueprint class instead. My guess is that it doesn’t based on how ImplementsGetWorld() works.)

3 Likes

Let’s clarify that overriding GetWorld must be done is special way (so it doesn’t cause setting bGetWorldOverridden = false). So calling Super::GetWorld and/or GetOuter()->GetWorld() is forbidden

2 Likes

So, basically, overriding GetWorld() with return nullptr; solved problem for me.

1 Like

Clarifying on what gWesson said here is the way I inherited from UObject and it seems to work just fine.
Just a reminder the solution consists in creating your own Object class inheriting from UObject and implement the GetWorld function for it.
I took the GetWorld implementation from the AActor class. There might be a better way to do it but it hasn’t caused any bug for me at the moment.
In the Header:

UCLASS(Blueprintable)
class YourProjectAPI UWorldObject : public UObject
{
	GENERATED_BODY()

public:
	// Allows the Object to use BP_Functions
	class UWorld* GetWorld() const;
	class ULevel* GetLevel() const;
};

In the source file:

ULevel* UWorldObject::GetLevel() const
{
	return GetTypedOuter<ULevel>();
}

UWorld* UWorldObject::GetWorld() const {
	// CDO objects do not belong to a world
	// If the actors outer is destroyed or unreachable we are shutting down and the world should be nullptr
	if (!HasAnyFlags(RF_ClassDefaultObject) && ensureMsgf(GetOuter(), TEXT("Actor: %s has a null OuterPrivate in AActor::GetWorld()"), *GetFullName())
		&& !GetOuter()->HasAnyFlags(RF_BeginDestroyed) && !GetOuter()->IsUnreachable())
	{
		if (ULevel* Level = GetLevel())
		{
			return Level->OwningWorld;
		}
	}
	return nullptr;
}

You can then re-parent all your Object to your WorldObject (or whatever you fancy named it)

If anyone knows of any issue that this solution might or will cause I would gladly hear about it before my project explodes :smiley:

Here are some screenshots to be a little more explicit:
Header file:

SourceFile:

WorldObject reparented Blueprint

5 Likes

thanks for the detailed workable solution!