Hello,
I am having problems with custom blueprint events inside a singleton type class.
If I use the BlueprintNativeEvent specifier. the C++ implementation gets called, but not the blueprint override.
I’ve narrowed it down to being a result of the singleton pattern integration in C++. The reason for the Singleton Pattern is because I want the class to be instantiated once and call “Get” from anywhere. I find this odd, as if I had done this in blueprints, even with the singleton design pattern, it would have worked(Have many blueprint managers using the singleton pattern.The singleton ‘Get’ is done inside the VM).
The way I call the method that calls the event in C++ is by a delegate that is called from Blueprints. (Works for the C++ implementation).
.h
UCLASS(Blueprintable)
class QUESTASSET_API UQuestManager : public UObject
{
GENERATED_BODY()
public:
//QuestManagerUpdate Delegate
UPROPERTY(BlueprintAssignable, BlueprintCallable, BlueprintReadWrite, Category = "Quest", meta = (DisplayName = "Update Quest Manager"))
FQuestManagerUpdateDelegate QuestManagerUpdate;
//Singleton Get Method
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Quest | Manager", meta = (DisplayName = "Get Quest Manager"))
static UQuestManager* GetQuestManagerInstance();
//Kills the singleton
UFUNCTION(BlueprintCallable, Category = "Quest | Manager", meta = (DisplayName = "Kill Quest Manager"))
static void KillQuestManagerInstance();
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Quest", meta = (DisplayName = "Notify"))
void BeginNotify();
void BeginNotify_Implementation();
//Test delegate binding
UFUNCTION(BlueprintCallable, Category = "Quest | Manager", meta = (DisplayName = "TestPrint"))
void printString();
//Register Bindings
void CreateBindings();
// ~-- Begin UObject Overrides --~ //
virtual UWorld* GetWorld() const override;
// ~-- End UObject Overrides --~ //
private:
//Quest Manager Singleton Instance
static UQuestManager* QuestManagerInstance;
};
.cpp
UQuestManager* UQuestManager::QuestManagerInstance = nullptr;
DEFINE_LOG_CATEGORY(LogQuestManager);
UWorld* UQuestManager::GetWorld() const
{
#if WITH_EDITOR
if (GIsEditor)
{
return GWorld;
}
#endif // WITH_EDITOR
return HasAnyFlags(RF_ClassDefaultObject) ? nullptr : GetOuter()->GetWorld();
}
UQuestManager* UQuestManager::GetQuestManagerInstance()
{
if ((QuestManagerInstance != nullptr) && (IsValid(QuestManagerInstance)))
{
return QuestManagerInstance;
}
else
{
QuestManagerInstance = NewObject<UQuestManager>();
QuestManagerInstance->CreateBindings();
return QuestManagerInstance;
}
}
void UQuestManager::KillQuestManagerInstance()
{
QuestManagerInstance = nullptr;
}
void UQuestManager::BeginNotify_Implementation()
{
UE_LOG(LogQuestManager, Warning, TEXT("In Implementation!"));
}
void UQuestManager::printString()
{
UE_LOG(LogQuestManager, Warning, TEXT("Test String"));
QuestManagerInstance->BeginNotify();
}
void UQuestManager::CreateBindings()
{
if (QuestManagerUpdate.IsBound())
{
QuestManagerUpdate.RemoveAll(this);
}
QuestManagerUpdate.AddDynamic(this, &UQuestManager::printString);
}
Any thoughts?
Cheers,