Calling Interface Functions In C++

I am trying to implement an interaction system via an interface but am having trouble figuring out how to call functions in my interface via C++. I am able to call these interface functions in Blueprints with the message nodes.

Some answers online talk about using Execute_* functions but I can’t find any clear description on how to do this. I have tried casting with Cast<>() and InterfaceCast but these cause my project to crash.

Specifically, what I am trying to do is run a trace to see if there are any actors in front of the player pawn that implement my InteractableInterface. And then I want to be able to call the Interact(…) function on that actor. My InteractableInterface code is shown below.

Any help would be appreciated.
Thanks very much

   UINTERFACE(meta = (CannotImplementInterfaceInBlueprint))
    class UInteractableInterface : public UInterface
    {
    	GENERATED_UINTERFACE_BODY()
    
    };
    
    class IInteractableInterface
    {
    	GENERATED_IINTERFACE_BODY()
    
    public:
    	UFUNCTION(BlueprintCallable, Category = Interact)
    	virtual bool IsInteractable()=0;
    
    	UFUNCTION(BlueprintCallable, Category = Interact)
    	virtual void Interact(AKillablePawn* Instigator)=0;
    };

Try this:

if (YourActor->GetClass()->ImplementsInterface(UInteractableInterface::StaticClass()))
{
  IInteractableInterface::Execute_Interact(YourActor); // This is the Execute_* function. The asterisk means your function name. :)
}

Upon compilation I get Execute_Interact is not a member of IInteractableInterface. I found another error in my code and I was able to cast to IInteractable Interface successfully with Cast < InteractableInterface > (ActorRef);

Thanks for the input

1 Like

I use them extensively, here’s an example:

.h (blueprint callable interface, but implemented in c++)

#pragma once
//this is important for the auto-generated executed functions.
#include "EntityInterface.generated.h"

/** Interface for actors which can be associated with teams */
/** Class needed to support InterfaceCast<IToStringInterface>(Object) */
UINTERFACE(meta = (CannotImplementInterfaceInBlueprint = true))
class UEntityInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};

class IEntityInterface
{
	GENERATED_IINTERFACE_BODY()

	/** returns the owner number of the actor (0=world, otherwise it's a player) */
	UFUNCTION(BlueprintCallable, Category = "ImperoEntities")
	virtual int32 GetOwnerNum() const = 0;

	/** sets the owner number of the actor */
	UFUNCTION(BlueprintCallable, Category = "ImperoEntities")
	virtual void SetOwnerNum(const int32 OwnerNum) = 0;

	/** returns the id number of the actor */
	UFUNCTION(BlueprintCallable, Category = "ImperoEntities")
	virtual int32 GetEntityId() const = 0;

	/** sets the id number of the actor */
	UFUNCTION(BlueprintCallable, Category = "ImperoEntities")
	virtual void SetEntityId(const int32 NewEntityId) = 0;

	/** Remove the given amount from entity's healt (net unsafe) */
	UFUNCTION(BlueprintCallable, Category = "ImperoEntities")
	virtual void ApplyDamage(int32 Amount) = 0;
};

another .h (Blueprint implementable events)

#pragma once

#include "SelectableInterface.generated.h"

/** Interface for actors which can be associated with teams */
/** Class needed to support InterfaceCast<IToStringInterface>(Object) */
UINTERFACE()
class USelectableInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};

class ISelectableInterface
{
	GENERATED_IINTERFACE_BODY()

	/** tries to select actor */
	UFUNCTION(BlueprintImplementableEvent, Category = Selection)
	void OnSelectionGained();

	/** tries to deselect actor */
	UFUNCTION(BlueprintImplementableEvent, Category = Selection)
	void OnSelectionLost();

	UFUNCTION(BlueprintImplementableEvent, Category = Commands)
	bool DoOnTargetEvent(const TScriptInterface<IEntityInterface>& Target, const TEnumAsByte<EJobType::Type>& JobType);
};

.cpp (tip: you can implement more than one interface in only 1 cpp, as u can see)

#include "MyProject.h"
//#include "Interfaces/SelectableInterface.h"
//#include "Interfaces/MultipleSelectableInterface.h"

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

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

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

and here’s how i call the functions:

//i have multiple targets at once
TArray<IEntityInterface*> Subjects;
//fill the array somehow

//and then call the function on the interface
//note that this function is only declared in the interface,
//the implementation is on Blueprints side

for (IEntityInterface* Subject : Subjects)
{
    ISelectableInterface* s = Cast<ISelectableInterface>(Subject);
    //note that actually i'm using 2 different interfaces
    if (s)
    {
        s->Execute_DoOnTargetEvent(Cast<UObject>(s), Target, Job);
    }
}

Hope this helps you :slight_smile:

I forgot sorry, note that for the execute function you have to provide the UObject context (the Object on which you’re calling the function, as a child of UObject: i used a cast to a generic UObject, but if you already have a pointer of your class type, you can use that directly) as first parameter.

I have this same issue, any updates on the problem?

Execute_Interact was just an example i posted. You need to replace Interact with your function name. For example, if your function name is MyFunction then it should be Execute_MyFunction.

The Execute_* static function only exists on BlueprintImplementable/BlueprintNativeEvent UFUNCTIONs. By using CannotImplementInterfaceInBlueprint, Cast<InteractableInterface> is the correct approach.

7 Likes

I came across this topic when trying to solve a specific UInterface related issue and I thought I might add one important thing to the discussion.

There are actually 2 scenarios in which we’re calling UInterface functions in C++:

  1. When interface is inherited by C++ class
  2. When interface is added in the blueprint Class Settings

Each of those requires different handling in C++ when calling an interface function.
First scenario:

if (Cast<IInterface_MyInterface>(MyActor))
{
	Cast<IInterface_MyInterface>(MyActor)->Execute_MyInterfaceFunction(MyActor);
}

Second scenario (Note UInterface in the if statement and IInterface in the function call!):

if (MyActor->GetClass()->ImplementsInterface(UInterface_MyInterface::StaticClass()))
{
	IInterface_MyInterface::Execute_MyInterfaceFunction(MyActor);
}

Perhaps someone will find this information useful.

6 Likes