Interfaces And Blueprints - Epic Wiki

# Interfaces And Blueprints

From Epic Wiki

Jump to: navigation, search

Template:Rating Using interfaces with C++ and Blueprints can be a little tricky when the interface is implemented purely in Blueprints. Currently, when a Blueprint implements an Interface the C++ InterfaceCast<> type cast does not work.

Interface Cast Method auto MyInterface = InterfaceCast(ActorInstance); if (MyInterface) {

// Other code

}

What you need to do instead is:

(Originally discovered by Lion032, source)

Implements Interface Method if (ActorInstance->GetClass()->ImplementsInterface(UMyInterface::StaticClass())) {

// Other code

}

This will work for both C++ implemented interfaces and Blueprint implemented interfaces. From here, you can use the static Execute versions of the interface functions.

Header: UINTERFACE(MinimalAPI) class UMyInterface : public UInterface {

GENERATED_UINTERFACE_BODY()

};

class IMyInterface {

GENERATED_IINTERFACE_BODY()

public:

UFUNCTION(BlueprintImplementableEvent) void MyInterfaceFunction();

};

Interface function example: if (ActorInstance->GetClass()->ImplementsInterface(UMyInterface::StaticClass())) {

IMyInterface::Execute_MyInterfaceFunction(ActorInstance);

}

It is likely that the static Execute functions are generated by the Unreal Header Tool (UHT) only for interface functions that declare UFUNCTION(). This means that you can't make a virtual interface function which uses UFUNCTION() and intellisense won't pick them up.

# More Complete Example (Passing Self as Reference):

MyInterface.H:

class AMyActor;

UINTERFACE(Category = "My Interface", BlueprintType, meta = (DisplayName = "My Interface")) class MYMODULE_API UMyInterface : public UInterface { GENERATED_UINTERFACE_BODY() };

class MYMODULE_API IMyInterface { GENERATED_IINTERFACE_BODY() public: /// My Initialization Interface. UFUNCTION(Category = "My Interface", BlueprintNativeEvent, BlueprintCallable, meta = (DisplayName = "On My Interface Execute") void OnInitialized(const AMyActor* Context); };

MyActor.H: UFUNCTION(Category = "My Interface", BlueprintNativeEvent, BlueprintCallable, meta = (DisplayName = "On My Interface Call")) void OnInitialized(const AMyActor* Context);

MyActor.CPP:

void AMyActor::OnInitialized_Implementation(const AMyActor* Context) {

if (Context != this) {return;}

TArray<AActor*>Interfaces; // Pick only Actors with Interface, instead of iterating whole World: UGameplayStatics::GetAllActorsWithInterface(this,UMyInterface::StaticClass(),Interfaces);

for (const auto &Actor : Interfaces) {

// Try to Execute on C++ layer: const auto &Interface = Cast(Actor); if (Interface) {Interface->Execute_OnInitialized(Actor,Context);} else

// Else, Execute Interface on Blueprint layer instead: if (Actor->GetClass()->ImplementsInterface(UMyInterface::StaticClass())) { IMyInterface::Execute_OnInitialized(Actor,Context); }

}

}

void AMyActor::BeginPlay() { Super::BeginPlay();

// Fire off the Native Event, which is going to be received by all the other Actors: Execute_OnInitialized(this,this);

}

Notes: Example above is implemented with old GENERATED_UCLASS_BODY() instead of new GENERATED_BODY() one. If you want your Actor to receive C++ Interface calls instead of from Blueprint layer, your Actor must inherit from both AActor class and your Interface class, like so: class MYMODULE_API AMyActor : public AActor, public IMyInterface {...}

# Update and pointer to more detailed discussion

Thanks for this wiki; I think it is essential on getting interfaces to work properly. I wrote a longer discussion of what I think is going on with Blueprint and C++ interfaces at https://answers.unrealengine.com/questions/214147/grand-unified-cblueprint-cast-interface-explanatio.html which I thought readers of this topic might find useful. -Xarol

James Tan , Bruno Xavier

Retrieved from "https://wiki.unrealengine.com/index.php?title=Interfaces_And_Blueprints&oldid=717"

Categories: