Quick answer: Call interface functions through the generated IMyInterface::Execute_FunctionName(Object, args) static wrapper. The implementing class provides a FunctionName_Implementation body. Direct calls via IMyInterface*->Foo() bypass Blueprint overrides and often silently do nothing.

Here is how to fix Unreal Blueprint Interface not calling C++ implementation. You define IInteractable as a Blueprint Interface in C++. You make a door Blueprint that implements it and overrides OnInteract. You make a player character in C++ that calls OnInteract on whatever it is looking at. The door never receives the call. The function appears to fire — but the Blueprint override does not. Unreal’s interface system requires specific call patterns to work, and the mistakes do not produce compile errors.

The Symptom

A C++ caller invokes a function declared on an Interface. The target object has a Blueprint implementation that should override. The Blueprint override does not run. Either nothing happens, or a C++ fallback runs instead (when one exists).

Variant: the code compiles, runs without warnings, but the Blueprint breakpoint on the event node never hits. Adding a UE_LOG to the C++ _Implementation confirms that the default runs, not the Blueprint override.

What Causes This

Direct interface pointer call. If you have IInteractable* Target = Cast<IInteractable>(Actor) and call Target->OnInteract(), that is a pure C++ virtual call. It invokes the C++ default implementation. Blueprint overrides live in the UClass’s function table, not the C++ vtable. The Blueprint side is completely bypassed.

Missing Execute_ wrapper. The correct way to call an interface function that might be overridden in Blueprint is IInteractable::Execute_OnInteract(Actor, args). This static wrapper is generated by UHT. It checks Blueprint first, then falls back to C++. Skipping this is the most common cause of “my Blueprint override does nothing.”

ImplementsInterface check. Calling Execute_ on an object that does not implement the interface results in an error and potentially a crash (in shipping). Always check with UKismetSystemLibrary::DoesImplementInterface or Actor->GetClass()->ImplementsInterface(UInteractable::StaticClass()) before calling Execute_.

Wrong UFUNCTION signature. The C++ declaration must use UFUNCTION(BlueprintNativeEvent) or UFUNCTION(BlueprintImplementableEvent) for Blueprint to be able to override. Plain UFUNCTION() on interface methods is Blueprint-callable but not overridable.

Class not tagged Blueprintable. The interface itself must be UINTERFACE(Blueprintable). Without it, Blueprint cannot see the interface in its class picker to implement it.

The Fix

Step 1: Define the interface correctly.

// Interactable.h
// -- Interface declaration
UINTERFACE(MinimalAPI, Blueprintable)
class UInteractable : public UInterface
{
    GENERATED_BODY()
};

// -- The actual interface
class MYGAME_API IInteractable
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Interaction")
    void OnInteract(AActor* Instigator);
};

The two-class pattern is Unreal-specific: the U-prefixed class holds the UObject reflection data; the I-prefixed class holds the actual interface methods. Both are generated correctly by the “Create > C++ Class > Unreal Interface” wizard.

Step 2: Provide _Implementation in implementing class.

// DoorActor.h
UCLASS()
class ADoorActor : public AActor, public IInteractable
{
    GENERATED_BODY()

public:
    virtual void OnInteract_Implementation(AActor* Instigator) override;
};

// DoorActor.cpp
void ADoorActor::OnInteract_Implementation(AActor* Instigator)
{
    UE_LOG(LogTemp, Log, TEXT("Door interacted by %s"), *Instigator->GetName());
    // default door-opening logic
}

Note the _Implementation suffix. This is what Blueprint overrides when you create a Blueprint subclass and override OnInteract. The Blueprint event graph’s node replaces this implementation.

Step 3: Call via Execute_ from C++.

// PlayerCharacter.cpp
void APlayerCharacter::TryInteract()
{
    FHitResult Hit;
    FVector Start = GetActorLocation();
    FVector End = Start + GetActorForwardVector() * 300;

    if (GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Visibility))
    {
        AActor* Target = Hit.GetActor();
        if (Target && Target->GetClass()->ImplementsInterface(
            UInteractable::StaticClass()))
        {
            IInteractable::Execute_OnInteract(Target, this);
        }
    }
}

This is the correct pattern: check ImplementsInterface, then call via Execute_OnInteract. The Execute_ wrapper handles finding the right function body — Blueprint override, _Implementation, or generating a warning if neither exists.

Step 4: Implement in Blueprint. Create a child Blueprint of ADoorActor. In Class Settings, add Interactable to Interfaces (if not already inherited). In the event graph, right-click and pick “Event On Interact” — the override node. Place interaction logic there. The Blueprint override now runs instead of (or alongside, if you call Parent) the C++ _Implementation.

BlueprintNativeEvent vs BlueprintImplementableEvent

Use NativeEvent for sensible defaults (“fall back to this behavior if Blueprint does not override”). Use Implementable for pure Blueprint contracts.

Blueprint-to-Blueprint Calls

From a Blueprint caller, calling an interface method is done by dragging off the target and searching for the interface function name. Blueprint automatically uses the Execute_ pattern under the hood — no special setup needed. The bug is mostly C++-side.

Debugging

If the call “silently does nothing,” log in both C++ _Implementation and Blueprint event. If C++ fires but not Blueprint, the Blueprint override is not actually wired up — check Class Settings > Implemented Interfaces. If neither fires, the Execute_ call is not reaching this object — check ImplementsInterface on the target.

“Interfaces are Unreal’s most powerful extensibility tool and its most fragile. Learn the Execute_ pattern once and save yourself a decade of bugs.”

Related Issues

For GAS integration, see Unreal GameplayAbility Not Activating. For input binding, Enhanced Input Action Not Firing covers related UFUNCTION setup.

Execute_FunctionName(Object, args) is the pattern. _Implementation in the cpp. Never call pointer directly.