UObject vs Actor event graphs

I’m trying to make a skill system that allows skills to have their implementation be defined through blueprint event graphs. Having noticed that blueprints inheriting from UObject can also have event graphs, I decided to make my C++ Skill base class inherit from UObject rather than Actor because Actor has a lot of unnecessary overhead for my purposes. The problem I’m encountering though is that UObject event graphs don’t have access to global blueprint functions like GetGameMode or any Blueprint Function Libraries.

Does anyone know if it is possible to get access to these functions, other from the obvious choice of inheriting from Actor?

Some nodes missing, because UObjects, do not provide world context by default (although they have virtual function GetWorld()).

It’s reported as intended behaviour, although I still disagree with it.
I should be able to provide custom world context for functions, which require it, and be able to use them from UObject classes inside blueprints.

Right now to work around this, I have to either rewrite those functions, or wrap them into custom piece of code, which is kind of counter productive.

Ah, I figured it had something to do with UObject having no world context so I tried overriding



	virtual class UWorld* GetWorld() const;
	class UWorld* GetWorldChecked(bool& bSupported) const;
	bool ImplementsGetWorld() const;


In my opinion too that should make those functions accessible. Thanks for sharing your knowledge. :slight_smile:

Edit: Deleted outdated findings

Okay, actually scratch what I said before. Good news, overriding GetWorld() does give your UObject event graph access to all static functions, like GetGameMode, GetAllActorsOfClass and your own blueprint function libraries (both C++ and BP assets). The only thing you need to make sure is that your implementation does not in some way call the original UObject::GetWorld() method, because when the original method is called, the UObject base class concludes that you haven’t overriden GetWorld.

In my case, I called the original UObject::GetWorld by accident via Outer->GetWorld() where Outer did not have a custom implementation. But now I return a custom UWorld * pointer or simply NULL if its not available and the world context dependent blueprint nodes become available. So there you have it, world context dependent blueprint nodes available in UObject event graphs. :smiley:

Skill.h:



class MYGAME_API USkill : public UObject
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category=MyGame)
	void ExecuteSkill();

	// Begin UObject interface
	virtual class UWorld* GetWorld() const override;
	// End UObject interface

	// Set this to a valid world right after creation
	UPROPERTY(Transient)
	UWorld * World;
}


Skill.cpp:



UWorld* USkill::GetWorld() const
{
	return World;
}


Edit: image and example code added

Thanks for sharing your research NisshokuZK !

:slight_smile:

Rama

You’re welcome Rama. :slight_smile: I’m glad we can have light weight but powerful event graphs!

Hi Zhi Kang Shao,

I’ve been trying to reproduce what you’ve done here was there anything else that enabled you to get this working? I’m trying to create UObjects that have access to standard functions and you’re the only person that I’ve found that has had any success with this.

Thanks!

To try help whoever might come across this in future and hopefully save them some frustrating hours.

I found that the GetOuter way works within this if check as below. Shout out to UKaosSpectrum on the Unreal discord for the code


UWorld* UCustomObject::GetWorld() const
{
    if (!HasAnyFlags(RF_ClassDefaultObject))
    {
        return GetOuter()->GetWorld();
    }
    else
    {
        return nullptr;
    }
}

The .h just has


virtual class UWorld* GetWorld() const override;

2 Likes