BlueprintNativeEvent - Override TestFunc in grandchild, then child, results in grandchild's override becoming TestFunc_0

bool AParent::TestFunc_Implementation() { unimplemented() return false; }

You define this in your cpp, but don’t declare it in your .h? Or did you just not show that part of your .h? That might be it.

If I have an abstract parent class with BlueprintNativeEvent, the child class can override my function fine and will call the function when called by its base class in the world. However, I remove this function - I do not need it. Instead, I create a grandchild that overrides the function. In a vacuum, this normally works (although sometimes it does not, but I can’t reproduce it reliably).

However, if I return to the child class and override the function, the grandchild’s override becomes a new function entirely.

Reproducing the problem:

I have an abstract class in C++. We’ll call it Parent.

UCLASS(abstract, Blueprintable)
class PROJECT_API AParent : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	AParent();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	bool TestFunc();
//Etc...

In my cpp file TestFunc looks like this:

bool AParent::TestFunc_Implementation()
{
	unimplemented()
	return false;
}

This compiles fine. I will now go into Unreal Engine 4’s editor and Create Blueprint class based on Parent. We’ll name this blueprint class Child.

And now this is where the problem arises. I will Create Blueprint class based on Child. I call it Grandchild… All it does is override Test Func and print out “Grandchild”. I now go and override Test Func in Child.

I drop Grandchild into the world. I go into Level Blueprint, and on BeginPlay() tell it to…

  • Get all by class: Parent → For Each Loop
  • For Each Loop → Loop Body
  • Loop Body → Test Func

128557-functioncall.png

And now the problem: It prints “Child,” not “Grandchild”…

What seems to happen is that if Grandchild has Test Func defined and we then also override in parent, Grandchild’s Test Func becomes Test Func 0, which is not the same function.

Note:

This problem does not occur that I can tell if the original function is of type void, ie…

 //.h file
 UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
 void TestFunc();

And…

  //.cpp
 void AParent::TestFunc_Implementation()
 {
     unimplemented()
 }

The first code section is the .h file, TestFunc is the virtual func, TestFunc_Implementation is the implementation of the virtual func in the abstract parent class.

Hello Drunkenvalley,

Thank you for reporting this issue. I’ve placed a bug report in for this issue which you can find here: UE-42687. It seems that the issue you’re seeing is dependent on the order that the overrides are created in, deferring to the newly created ones in inherited classes, so you should be able to workaround it in the time being with that knowledge.

Have a nice day!

Yes, we worked around it to, but boy was it frustrating when we were having “Child” rather than “Grandchild” printed. :stuck_out_tongue: (Not literally those names, but.)