5.1 // Calling C++ interface function does not execute BP event implementation

Hi everyone,

I am relatively new to C++ and working to move certain functionalities out of blueprints. Any help or pointers in the right direction would be highly appreciated! :sparkles:

To start, here are my classes:

UCelestialSkySubsystem // inherits from UEngineSubsystem
UCelestialSkyInterface & ICelestialSkyInterface // cpp interface
ACelestialActorBase // cpp class inheriting from AActor and ICelestialSkyInterface
BP_CelestialBody // abstract BP class inheriting from ACelestialActorBase
BP_Planet // inherits from BP_CelestialBody and implements interface events

I have a function in my subsystem that updates a number, then calls an implemented interface event on each actor in an array of ACelestialActorBase actors—I know these are BP_Planet actors spawned into the world.

The problem is that calling the Execute_Prefix function in my subsystem does not call the implemented event in my BP_Planet actors.

Based on findings in this thread (C++ Interface implemented in BP is null) and the others linked inside it, I know that my BP actors must inherit the interface from a cpp class. I think I have done this properly (see my classes above)—everything compiles, no errors, no crashes, but simply nothing happens when calling Execute_OnElapsedTimeChanged.

I do not have C++ implementations for the interface methods.

The subsystem’s function is SetElapsedTime and the interface method is OnElapsedTimeChanged.

CelestialSkySubsystem.cpp (click to show)
void UCelestialSkySubsystem::SetElapsedTime()
{
	// [...set ElapsedTime code...]

	// Make an array of values from TMap CelestialBodyActorReferences.
	TArray<ACelestialActorBase*> CelestialActors;
	CelestialBodyActorReferences.GenerateValueArray(CelestialActors);

	// For each CelestialActor, call the OnElapsedTimeChanged interface function.
	for (ACelestialActorBase* CelestialActor : CelestialActors)
	{
		bool bImpl = UKismetSystemLibrary::DoesImplementInterface(CelestialActor, UCelestialSkyInterface::StaticClass());
		if (bImpl) // this returns true.
		{
			ICelestialSkyInterface::Execute_OnElapsedTimeChanged(CelestialActor); // this is the part where nothing happens.
		}
	}
}
CelestialSkyInterface.h (click to show)
#pragma once

#include "CoreMinimal.h"
#include "CelestialSkyInterface.generated.h"

UINTERFACE()
class UCelestialSkyInterface : public UInterface
{
	GENERATED_BODY()
};

class CELESTIALSKY_API ICelestialSkyInterface
{
public:
	GENERATED_BODY()

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "CelestialSky|Time")
		void OnElapsedTimeChanged();
}

BP_Planet implementation:

OnElapsedTimeChanged

The PrintString does not do anything when Execute_OnElapsedTimeChanged is called.

Here is the BP equivalent of what I’m trying to achieve in C++:

This BP equivalent works flawlessly when being used in my editor utility widget, but I am having a great deal of trouble getting this over to C++.

Please help! Thanks again!

My best and only guess is that it has to do with my EngineSubsystem possibly(?) existing on a separate background thread from the game thread. I’m going to try to work around this by having two separate subsystems—one for use in the editor and one for use at runtime. My plugin already has two separate modules for this purpose so it should work out.

Hey ebuch, I was just facing this issue as well (I was here looking for answers haha). I don’t have an Editor part like you do but I just fixed my issue by having the C++ class inherit from the interface class directly in C++ instead of adding it to the BP. I’m not sure that applies to you but definitely try it out if you’ve still not solved this.

Hey thanks for the reply! I did get my implementation working a while back—here’s my current setup, in the hopes that it will assist someone else in the future:

I have an engine subsystem that keeps track of a time clock. When my actors are spawned, they subscribe to the subsystem and then receive an interface function call every time the time changes.

Interface header file
UINTERFACE()
class UCelestialTimeInterface : public UInterface
{
	GENERATED_BODY()
};

class CELESTIALSKY_API ICelestialTimeInterface
{

	GENERATED_BODY()
	
public:
	UFUNCTION(BlueprintNativeEvent)
	void OnCurrentTimestampChanged(double CurrentTimestamp);
	virtual void OnCurrentTimestampChanged_Implementation(double CurrentTimestamp) {}
};

Subscribe & Unsubscribe functions
void UCelestialTimeSubsystem::SubscribeToTimeChanges(UObject* Subscriber)
{
	if (Subscriber && Subscriber->GetClass()->ImplementsInterface(UCelestialTimeInterface::StaticClass()))
	{
		SubscribedObjects.AddUnique(Subscriber);
	}
}

void UCelestialTimeSubsystem::UnsubscribeFromTimeChanges(UObject* ObjectToUnsubscribe)
{
	SubscribedObjects.RemoveSingleSwap(TWeakObjectPtr<UObject>(ObjectToUnsubscribe));
}
Notify subscribers function
void UCelestialTimeSubsystem::NotifyCurrentTimestampChanged(const double NewTimestamp)
{
	for (TWeakObjectPtr<UObject>& Subscriber : SubscribedObjects)
	{
		if (!Subscriber.IsValid())
		{
			continue;
		}
		if (Subscriber->GetClass()->ImplementsInterface(UCelestialTimeInterface::StaticClass()))
		{
			ICelestialTimeInterface::Execute_OnCurrentTimestampChanged(Subscriber.Get(), NewTimestamp);
		}
		if (ICelestialTimeInterface* CelestialTimeInterface = Cast<ICelestialTimeInterface>(Subscriber))
		{
			CelestialTimeInterface->OnCurrentTimestampChanged_Implementation(NewTimestamp);
		}
	}
}

Execute_OnCurrentTimestampChanged() calls Blueprint implementations.
OnCurrentTimestampChanged_Implementation() calls C++ implementations.

This works regardless of whether the interface was inherited in C++ or implemented directly into a Blueprint (I’m using an editor utility widget).