Check if actor implement an interface failure

Hello there,

I’m playing a bit with UE4 UInterface so I searched for tutorial and guide, using mainly:

InterfaceDocs

HowToMakeInterfacesImplementableByBlueprints

Rama_guide

and I come out with this BaseImplementation:

BaseStrategy.h (interface)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Object.h"
#include "StrategyBase.generated.h"

class AGenerator;
/**
 * 
 */
UINTERFACE(BlueprintType)
class CANDLEPROJECT_API UStrategyBase : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};  

class IStrategyBase
{
	GENERATED_IINTERFACE_BODY()

public:
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "GenerationStategyBase Interface")
	void Generate(AGenerator* InGenerator);
};

BaseStrategy.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "StrategyBase.h"
#include "Generator.h"

UStrategyBase::UStrategyBase(const class FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{

}

void IStrategyBase::Generate_Implementation(AGenerator* InGenerator)
{
	UE_LOG(LogTemp, Error, TEXT("Should not see this, missing override?"));
}

//void IStrategyBase::Generate(AGenerator* InGenerator)
//{
//	UE_LOG(LogTemp, Error, TEXT("Should not see this, missing override?"));
//}

StrategyNotComplex.h (AActor implementing the interface)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "StrategyBase.h"
#include "StrategyNotComplex.generated.h"

class AGenerator;
/**
 * 
 */
UCLASS(BlueprintType)
class CANDLEPROJECT_API AStrategyNotComplex : public AActor, public IStrategyBase
{
	GENERATED_BODY()

public:
	AStrategyNotComplex ();

	/*UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "GenerationStategyBaseInterface")
	void Generate(AGenerator* InGenerator);*/
	virtual void Generate_Implementation(AGenerator* InGenerator) override;
};

StrategyNotComplex.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "GenerationSingleTile.h"
#include "Generator.h"
#include "Engine/World.h"

AStrategyNotComplex::AStrategyNotComplex()
{
	UE_LOG(LogTemp, Error, TEXT("Constr AStrategyNotComplex"));
}

#pragma optimize("", off)
void AStrategyNotComplex::Generate_Implementation(AGenerator* Generator)
{
	/* make stuff */
}

So the idea is that in this way I can create different actor with different logics and call always Generate if they have this interface:

where the magic DOESN’T happen:

somewhere in a .cpp

void AGenerator::Generate(UObject* WorldContextObject)
{
	
	IBaseStrategy* strategy = Cast<IBaseStrategy>(GenerationStrategy);
	if (strategy)
	{
		strategy->Generate(this);
	}
	else
	{
		if (GenerationStrategy->Implements<UBaseStrategy>())
		{
			IBaseStrategy::Execute_Generate(GenerationStrategy, this);
		}
		else
		{
			if (GenerationStrategy->GetClass()->ImplementsInterface(UBaseStrategy::StaticClass())) 
			{
				IBaseStrategy::Execute_Generate(GenerationStrategy, this);
			}
			else
			{
				UE_LOG(LogTemp, Error, TEXT("%i"), GenerationStrategy->Interfaces.Num());
				for (int i = 0; i < GenerationStrategy->Interfaces.Num(); i++)
				{
					if (GenerationStrategy->Interfaces[i].Class->GetName() == "BaseStrategy")
					{
						UClass* interfaceClass = GenerationStrategy->Interfaces[i].Class;
						UFunction* interfaceFunction = interfaceClass->FindFunctionByName("Generate");

						IBaseStrategy* strategy2 = Cast<IBaseStrategy>(interfaceClass);
						if (strategy2)
						{
							strategy2->Generate(this);
						}
					}
				}
			}			
		}		
	}
}

None of the if conditions are ever verified.
What is GenerationStrategy?

simply:

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Logic", meta = (MustImplement = "BaseStrategy"))
	TSubclassOf<UObject>	GenerationStrategy;

That it’s set from editor passing only objs that implements BaseStrategy (already automatically selectable in the drop down menu of the editor). In this case:

  • a StrategyNotComplex itself
  • a StrategyNotComplexBP, a BP created from StrategyNotComplex

Actually GenerationStrategy is the BP version.

Watching the GenerationStrategy element inside the function I can clearly see in GenerationStrategy->Interfaces[i].Class->Interfaces that BaseStrategy is contained, however none of the condiction is fulfilled and Execute_Generate(…,…) it’s never called.

What I’m missing?

I can implement this in many other modes (probably better), but I’m curious about what I’m missing to work with UInterfaces.

Thanks.