C++ Cast Blueprint To Parent Class Fail

Hi, I have a Blueprint (UIManagerBP) that extends UIManager.h ( which extends UObject )

When I’m trying to instantiate the blueprint using ConstructorHelper and then casting it back to (UUIManager*), the cast fail, at this point i have tryed almost every solution I have found here like StaticLoadObject or using Cast<>(), but nothing seem to work

UGameInstanceS::UGameInstanceS(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{

	static ConstructorHelpers::FObjectFinder<UClass> uiManagerBP(TEXT("/Game/Blueprints/Manager/UIManagerBP.UIManagerBP_C"));
	uiManager = (UUIManager*)uiManagerBP.Object;
}

Thanks for any help !

You must use Cast function

uiManager = Cast<UUIManager>(uiManagerBP.Object);

Hi, unfortunately I already tried using the Cast<>() method, but It still returning me NULL

ok that mean uiManagerBP.Object is NULL, u can put checking before Cast, and remove .UIManagerBP_C in the end and try again

The uiManagerBP.Object is not NULL, and that is what it drive me crazy for the past 5 hour.
removing _C make the editor to drop this message :

Default Property warnings and errors: Error :CDO Constructor (GameInstanceS): Failed to find /Game/Blueprints/Manager/UIManagerBP.UIManagerBP

this confirm the fact that the Object var isn’t NULL

Oh, just realize u load it in GameInstance, it not gonna work there, you must load in StartGameInstance or any function call after that. Here my code to get the class from blueprint LoadingUIClass is TSubclassOf ULoadingWidget, u can change to StaticLoadObject if you want.

LoadingUIClass = StaticLoadClass(ULoadingWidget::StaticClass(), NULL, *LoadingUIAsset.ToString());

with

UPROPERTY(config, meta = (AllowedClasses = "LoadingWidget"))
	FStringAssetReference LoadingUIAsset;

and in config file

LoadingUIAsset=/Game/SUAssets/UI/SlateBluePrints/LoadingUI.LoadingUI_C

Oh, you cannot put that in constructor of GameInstance, you need to get that in StartGameInstance or any function is call after when game start or another class instance.

Do you mean I cannot use the ConstructoHelper inside the constructor of GameInstance ? or i can’t cast to my UUIManarger class in GameInstance’s constructor ?

I want to put these variable in GameInstance because the manager must survive between level.

The cast fails because your uiManagerBP.Object is a UClass, not an instance of the class. You need to actually construct an instance.

For some reason, it looks like this is rather awkward to do with the FObjectInitializer when you are dealing with a dynamic UClass. Using the non-template version as follows may work:

uiManager = Cast<UUIManager>(ObjectInitializer.CreateDefaultSubobject(
  this,
  TEXT("WhateverInstanceNameYouLike"),
  uiManagerBP.Object,
  uiManagerBP.Object,
  false,
  false,
  false));

I haven’t ever needed to do this though, so I’m not certain it will work.

2 Likes

Thanks! that solved my issues !!

HI, I’m trying to work this out as well.

From what I’ve discovered from blueprints, you can’t guarantee that an instance (object) of another class has been created in any particular order (unless they are objects that you have spawned in a specific order in your own boot sequence), as this is defined/decided somehow in the UE4 engine (i.e. if you try to get a reference to another object from this objects constructor, if this object is being constructed first, then the other object won’t exist yet).

For example (from my experience), player controller seems to be spawned before the level blueprint, so if I want to initialise player controller with some data from the level blueprint you have to implement a PostInit() function that basically waits until the level blueprint has registered itself as having been constructed with myGameMode, then once all objects have registered with myGameMode it then calls a PostInit() function on my player controller that can now get the needed data from the level blueprint (not sure if this is how you have to do it, but it works) (for some classes their BeginPlay() and Tick() events even start running before others have even been constructed).

I don’t know if this is definitively the way it is (I’m still trying to work it out myself), but it certainly seems to be from some tests I’ve run.

P.s.:

uiManager = Cast<UUIManager>(uiManagerBP.Object);

From what I’ve read this is the correct UE4 casting syntx (the version you’re using is the C++ syntax).

this confirm the fact that the Object var isn't NULL  

Are you getting this error at compile time or run-time (and in Visual Studio or in UE4)?

I am having a bit of the same problem, but I am hoping to construct the instance outside of the constuctor. Is there a way to do this using NewObject?

Yes.

NewObject< UMyObjectBaseType >(this /* or whatever outer you want */, MyUClassPtr);

Hey kamrann, thanks for the reply!

Sorry, still a little confused… I have an Actor class blueprint selected in the Content Browser and I am trying to get the components inside the blueprint but the Actor class I am getting back from the blueprint has an empty OwnedComponents.

Here is my code:

FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
TArray<FAssetData> SelectedAssets;
ContentBrowserModule.Get().GetSelectedAssets(SelectedAssets);
UBlueprint* LoadedObject = Cast<UBlueprint>(SelectedAssets[0].GetAsset());
AActor* BPClass = NewObject<AActor>(GetTransientPackage(), LoadedObject->ParentClass);

TArray<UActorComponent*> comps;
BPClass->GetComponents(comps);
for (int32 i = 0; i < comps.Num(); i++)
{
	// Do Stuff in here
}

Any advice?

Generally you can’t use NewObject for AActor-derived classes, you should use UWorld::SpawnActor instead. But here you’re obviously trying to do something outside of the scope of a specific world, so I’m not sure.

I don’t know exactly what you’re planning to do with the components, but it looks like you should perhaps be using GetDefaultObject rather than constructing a new one?

Maybe try:

AActor* CDO = LoadedObject->GeneratedClass->GetDefaultObject< AActor >();
CDO->GetComponents(comps);

(You were using LoadedObject->ParentClass, but if you want the class associated with the blueprint, you should use GeneratedClass).