Gameplay Statics functions not visible in Blueprint

I’m create my own class(from Editor), for example UPresenter, inherited from UObject. There is no content, just empty class. Later, i’m create blueprint, inherited from UPresenter: BP_Presenter. So, when i trying to insert node Get Game Instance… it’s not found in “Right-Click” and many other important functions of Gameplay Statics too. I know, by architecture object is not “in world”, not in gameplay, so it can’t participate in it.

There is a question: what is minimal C++ code to allow inherited from native class blueprint use Gameplay Statics? Without inheriting it from AActor, of course.

1 Like

I’m having this problem as well in UE 4.10. Don’t suppose you found a solution?

The only thing I could think of would be to include the GameplayStatics library in the class’s source and then create custom functions which call each function you need from GameplayStatics. That is definitely a hacky way to do it, but it’s all I can think of at the moment.

I don’t think this is something you can do in Blueprints though?

If you make the custom functions in code with the UFUNCTION specifier and make the function BlueprintCallable, and have those custom functions call the GameplayStatics functions you need, it should work in the same way.

I don’t get it… this doesn’t make sense. I’m sure there’s a better way to do this.

Objects like BehaviorTree task are all able to access GameplayStatics. How are they able to do this?
How do you get it to ‘participate’ in game?

Your class needs to effectively override the GetWorld function.

According to the code (no documentation references found for this), “effectively” means that it can at no point call “UObject::GetWorld()” - even on another object.

call flow is:

right click in blueprint editor
UEdGraphSchema_K2::CanFunctionBeUsedInGraph
UObject::ImplementsGetWorld() Line 661	C++
a static bool 'bGetWorldOverridden' is set to 'true'
GetWorld() is called.
 *** if UObject::GetWorld() is ever called, this will set bGetWorldOverridden to false
 return bGetWorldOverridden (the value of GetWorld() is not actually used at this time)

so: implement GetWorld() and you will be able to access those functions now.

note that if you don’t implement it PROPERLY, this may crash or not return the data you were expecting
ie: you probably need to actually return a real and appropriate UWorld* for your object

example GetWorld() that works:

UWorld* UArcHitGameEffect::GetWorld() const
{
	UObject *outer = GetOuter();
	if (outer && outer->IsA<AActor>() && !outer->HasAnyFlags(RF_ClassDefaultObject))
	{
		return outer->GetWorld();
	}

	return nullptr;
}

example that doesn’t:

UWorld* UArcHitGameEffect::GetWorld() const
{
	UObject *outer = GetOuter();
	return outer ? outer->GetWorld() : nullptr;
}

The reason the second won’t work, is that it accesses the Outer, regardless of type, which could very likely be - and in fact, probably is during blueprint editing - a UObject derived class with no GetWorld override of its own… resulting in the invalidation mentioned above. Oops!

1 Like

Thanks! Also remember the class has to be Blueprintable:

The .h file:

UCLASS(BlueprintType, Blueprintable)
class UMyObject : public UObject {  
  GENERATED_BODY()
  public:
    UWorld* GetWorld() const;
};

The .cpp file:

UWorld* UMyObject::GetWorld() const {
  UObject *outer = GetOuter();
  if (outer && outer->IsA() && !outer->HasAnyFlags(RF_ClassDefaultObject)) {
    return outer->GetWorld();
  }
  return nullptr;
}