Hello there,
I’m playing a bit with UE4 UInterface so I searched for tutorial and guide, using mainly:
HowToMakeInterfacesImplementableByBlueprints
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.