Casting UBlueprint to actual Parent Class

Hi,

i just cant get any solution for the following issue:

I want a list of Blueprints to be assigned to a custom Blueprint through the editor and then worked with in code.
First i made a new Blueprint out of the HUD containing:



UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = )
TArray<UBlueprint*> Elements;


Then i made a new Class UTest : UObject with the Blueprintable directive, created a new Blueprint in the editor using UTest as parent class, and added that blueprint then into the Elements of the HUD.

So far so good.

Now, in the actual implementation i iterate over the TArray and want the actual BaseClass of the Blueprint:



	for (TArray<UBlueprint*>::TIterator eleIter(Elements); eleIter; ++eleIter) {
		UBlueprint* current = *eleIter;
		if (current) {
			UTest* currentElement = Cast<UTest>(current);
			currentElement->GetCustomStuff();


Now the cast does fail and currentElement is NULL.

The Question is: How can i cast the UBlueprint back to the actual Parent Object? Is there some special property i need to get?

Thanks!
Cheers,

If you go to Blueprint.h


/** Pointer to the parent class that the generated class should derive from */
	UPROPERTY(AssetRegistrySearchable)
	TSubclassOf<class UObject>  ParentClass;

You should be able to access the parent class directly :slight_smile:


current->ParentClass;

Let us all know if that works!

there’s also this, which I always thought was rather nifty:


/** 
	 * Gets an array of all blueprints used to generate this class and its parents.  0th elements is the BP used to generate InClass
	 *
	 * @param InClass				The class to get the blueprint lineage for
	 * @param OutBlueprintParents	Array with the blueprints used to generate this class and its parents.  0th = this, Nth = least derived BP-based parent
	 * @return						true if there were no status errors in any of the parent blueprints, otherwise false
	 */
	static bool GetBlueprintHierarchyFromClass(const UClass* InClass, TArray<UBlueprint*>& OutBlueprintParents);

_


PS: I know your question is about casting

I’m hoping you will magically figure this out with some kind of additional inspiration from my above info

1 Like

Given that request, what suggested is the right way to convert a blueprint into a class. However, you shouldn’t be using blueprint pointers or arrays of blueprint pointers in general. Instead, point to the base class itself. This means you can exchange native C++ and Blueprint generated classes without worrying about the underlying type.

For example, you might do:
TSubclassOf<AActor> ActorClass;

Where you can replace AActor with whatever class name you want, or if it can literally be anything, use UClass* instead.

Cheers,
Noland

Hi ,

understood. Though, what would then be the correct way to achieve the following:

I have a Class UHudButton, which contains something like this:




UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = IndyHUD)
UTexture2D* ButtonUpTexture;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = IndyHUD)
UTexture2D* ButtonHoverTexture;

...


Now in the Editor i create a few Blueprint from that Class and assign each one the individual textures, i.e. for Start Game, for Quit, etc.

In my HUD Class (which i got blueprinted too) i then have want to have a list of UHudButton’s, each with it’s textures.

Of course i first tried with



TArray<UHudButton*> Elements;


though it’s still not supported to have a TArray with a BlueprintBaseClass (=UHudButton) and fill it from the Editor with the Blueprints that got this one as parent class.

I simply couldnt find a different way to not have all the textures for the buttons hardcoded, or have a hardcoded number of buttons, thus the TArray.

Any ideas?

Cheers,

TArray<UHudButton*> is an array of instances, not an array of classes.

TArray<TSubclassOf<UHudButton>> should allow you to pick subclasses of UHudButton in the details panel. If they’re just data assets, you can then use GetDefault to read the member variables:



for (TSubclassOf<UHudButton> ButtonClass : Elements)
{
	if (const UHudButton* DefaultInstance = ButtonClass->GetDefaultObject())
	{
		do something with DefaultInstance->ButtonHoverTexture, etc...
	}
}

Otherwise if those values are computed or change over time, you may need to instantiate the button class (NewObject<UHudButton>(Outer, Class)).

Cheers,
Noland

Hi ,

in the meanwhile i already figured out how to use TSubclassOf in the array correctly; Finally i understood the concept completely :wink:

Thanks to you and for the support!

Cheers,