BlueprintNativeEvent: function already has a body...?

I am trying to implement a BlueprintNativeEvent, but the compiler keeps telling me that the function already has a body. It’s an Interface-function and I declared it like this:

UFUNCTION(BlueprintNativeEvent)
UObject* OnLeftButtonEvent_BP(EKE Event, ACommanderPC* Commander);

The header contains both declarations and a few definitions, just in case that makes a difference for the reflection process.

The only reason I need a native fallback-implementation at all is to return NULL, actually. Which is why I don’t understand that the compiler doesn’t complain when I don’t write a native implementation at all or instead declare the function a BlueprintImplementableEvent. I mean, what’s the default return value then?..

Anyway, the implementation in the cpp file looks like this:

UObject* IInteractiveInterface::OnLeftButtonEvent_BP_Implementation(EKE Event, ACommanderPC* Commander)
{
	return _getUObject();
}

And the error message is:

1>D:\UnrealProjects\Project02\Source\Project02\Interfaces\InteractiveInterface.cpp(23): error C2084: function 'UObject *IInteractiveInterface::OnLeftButtonEvent_BP_Implementation(EKE,ACommanderPC *)' already has a body
1>  d:\unrealprojects\project02\source\project02\interfaces\InteractiveInterface.h(61): note: see previous definition of 'OnRightButtonEvent_BP_Implementation'

But there is no implementation anywhere… What am I doing wrong here?

The return value is just telling the player controller whether the object has consumed the input-event, redirected it to another object or lets it pass on (NULL), in case anyone wonders.

1 Like

I had the same problem when upgrading from 4.18 to 4.20 with my project.
It seems that UE 4.20 does not allow you to create a default implementation for a function if it is defined in an interface class. I was lucky that my code did not really depend on it.
You must remove the body in the CPP file and accept the default, empty implementation the meta compiler provides.
You can have native events only in function libraries or other classes but not in interfaces

1 Like

Ok… I just recently (after porting to 4.20) started to expose some interface functions to the engine and blueprints, so I wouldn’t know how it was before. I just remember that I had reasons to keep it strictly native, but that was years ago, when I first implemented an interface. I think I couldn’t have any default implementations at all, but my memory may be failing me here…

So, then I guess the default value for these functions is always false/NULL ??

It feels a bit strange declaring and calling a function with a return value and not giving it an implementation whatsoever. I guess I can just test it though…

1 Like

Yes it seems they always return false or null, nothing you can do about it. The answer I got when asking about it was that interfaces are not supposed to have a default implementation. Well, that’s the way it is now.

Then BlueprintNativeEvent and BlueprintImplementableEvent are effectively the same in interfaces.

For an interface yes, although I don’t know if there is a guarantee that Callable would return false/null as well, maybe the return values are undefined and may change in a later version if you dont provide an implementation. Callable means that you are supposed to provide one and I don’t what happens if you don’t. It may work now but not later. Unlikely, but possible. I would use Native in such a case just to be sure and make clear that there is a save default implementation

Declare or define the _Implementation member in the header, and make sure you’re using GENERATED_BODY, not GENERATED_IINTERFACE_BODY. Then UHT won’t generate a default XXX_Implementation body returning 0, and your version will work.

Tested in UE4 4.21.2.

I did (later) find a problem with this. When you derive from the interface in Blueprint, it always generates the BlueprintNativeEvent’s implementation in the Blueprint, with nothing connected to the return value. And it’s not possible to super-call from there.

So the default implementation will only work for C++ implementations of the Interface, Blueprint implementations of the Interface will never hit the default implementation.

This seems like a bug to me, as the behaviour shouldn’t be different, I think.