How to properly use "_Implementation" to allow blueprints to override C++ functions?

Ive tried following the pickupbattery tutorial, but it doesn’t seem to work.

DMagicGameMode.h

#pragma once

#include "GameFramework/GameMode.h"
#include "DMagicGameMode.generated.h"

UCLASS(blueprintable)
class ADMagicGameMode : public AGameMode
{
	GENERATED_BODY()

public:
	ADMagicGameMode(const FObjectInitializer& ObjectInitializer);

	UFUNCTION(BlueprintNativeEvent) void SetStringsDEBUG(int32 Index, FString Str);

};

DMagicGameMode.cpp

#include "DMagic.h"
#include "DMagicGameMode.h"

ADMagicGameMode::ADMagicGameMode(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

void ADMagicGameMode::SetStringsDEBUG_Implementation(int32 Index, FString Str)
{
}

Intellisense claims SetStringsDEBUG_Implementation is incompatible with its declaration.

.

ADMagicGameParent.h

#pragma once

#include "DMagicGameMode.h"
#include "DMagicGameParent.generated.h"


UCLASS()
class DMAGIC_API ADMagicGameParent : public ADMagicGameMode
{
	GENERATED_BODY()
	
public:
	ADMagicGameParent(const FObjectInitializer& ObjectInitializer);

	virtual void SetStringsDEBUG_Implementation(int32 Index, FString Str) override;
	
};

There is another Intellisense error here, but I am assuming it is because of the above error.

ADMagicGameParent.cpp

#include "DMagic.h"
#include "DMagicGameParent.h"



ADMagicGameParent::ADMagicGameParent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}


void ADMagicGameParent::SetStringsDEBUG_Implementation(int32 Index, FString Str)
{
	Super::SetStringsDEBUG_Implementation(Index, Str);
	Destroy();
}

These are the error messages received from a compile:

DMagicGameParent.h(19): error C3668: 'ADMagicGameParent::SetStringsDEBUG_Implementation' : method with override specifier 'override' did not override any base class methods

DMagicGameMode.cpp(28): error C2511: 'void ADMagicGameMode::SetStringsDEBUG_Implementation(int32,FString)' : overloaded member function not found in 'ADMagicGameMode'
	d:\documents\unreal projects\dmagic\source\dmagic\DMagicGameMode.h(9) : see declaration of 'ADMagicGameMode'
	d:\documents\unreal projects\dmagic\source\dmagic\DMagicGameMode.h(11) : see declaration of 'ADMagicGameMode::SetStringsDEBUG_Implementation'
	d:\documents\unreal projects\dmagic\source\dmagic\DMagicGameMode.h(9) : see declaration of 'ADMagicGameMode'

DMagicGameParent.h(19): error C3668: 'ADMagicGameParent::SetStringsDEBUG_Implementation' : method with override specifier 'override' did not override any base class methods
	d:\documents\unreal projects\dmagic\source\dmagic\DMagicGameMode.h(11) : see declaration of 'ADMagicGameMode::SetStringsDEBUG_Implementation'
	d:\documents\unreal projects\dmagic\source\dmagic\DMagicGameMode.h(9) : see declaration of 'ADMagicGameMode'

DMagic.generated.cpp(51): error C2511: 'void ADMagicGameMode::SetStringsDEBUG(int32,const FString &)' : overloaded member function not found in 'ADMagicGameMode'
	d:\documents\unreal projects\dmagic\source\dmagic\DMagicGameMode.h(9) : see declaration of 'ADMagicGameMode'

DMagic.generated.cpp(55): error C2352: 'UObject::FindFunctionChecked' : illegal call of non-static member function

This isn’t as crazy as it seems.

In 4.7 they change the behavior so that you need to declare the _Implementation function yourself.

 UCLASS(blueprintable)
 class ADMagicGameMode : public AGameMode
 {
     GENERATED_BODY()
 
 public:
     ADMagicGameMode(const FObjectInitializer& ObjectInitializer);
 
     UFUNCTION(BlueprintNativeEvent) 
     void SetStringsDEBUG(int32 Index, FString Str);
     void SetStringsDEBUG_Implementation(int32 Index, FString Str);
 };

That should work.

I added that declaration and it is now throwing errors at GENERATED_BODY()

DMagicGameMode.h(11): error C2338: Function SetStringsDEBUG was marked as Native, BlueprintEvent. Declare function void SetStringsDEBUG_Implementation(int32 , const FString& )  in class ADMagicGameMode.

It threw this error 9 times throughout the compile, all on ADMagicGameMode’s GENERATED_BODY() line.

Check your consts and refs maybe? What I pasted doesn’t have const FString&

Checking through everything, I noticed, none of the code I wrote has either ‘const’ or ‘FString&’

But the ‘DMagic.generated.cpp’ has:

IMPLEMENT_CLASS(ADMagicGameMode, 1577342677);
void ADMagicGameMode::SetStringsDEBUG(int32 Index, const FString& Str)
{
	DMagicGameMode_eventSetStringsDEBUG_Parms Parms;
	Parms.Index=Index;
	Parms.Str=Str;
	ProcessEvent(FindFunctionChecked(DMAGIC_SetStringsDEBUG),&Parms);
}

It seems it auto-generated it?
I am hesitant to touch that file tho, as the comment on top specifically says not to…

EDIT:

Instead, I tried unifying all FString entries to ‘const FString& Str’.
This removed all errors in ADMagicGameMode.h

But DMagicGameParent.h now has an error …

DMagicGameParent.h(19): error C3668: 'ADMagicGameParent::SetStringsDEBUG_Implementation' : method with override specifier 'override' did not override any base class methods

I find the unreal header tool a bit flaky. Try deleting the file and recompile

You might also want to try making the parameters on the string const ref just like the UHT is saying. They probably auto pass the string by const ref, it actually makes sense to do that.

Yea, I did that, but I am still trying to figure out why DMagicGameParent.h now has an error …

DMagicGameParent.h(19): error C3668: 'ADMagicGameParent::SetStringsDEBUG_Implementation' : method with override specifier 'override' did not override any base class methods

EDIT:

Removing the override bit at the end of 'DMagicGameParent.h’s SetStringsDEBUG_Implementation allowed it to compile successfully, Im about to test if it works in the editor.

That error suggests that the function looks something like.

void SetStringsDEBUG_Implementation(int32 Index, FString Str) override;

You don’t need the override.

It works now. Thank you much, you were very helpful. :slight_smile: