I’m brand new to the Unreal 4 API and C++ is still a new language to me, so I do most of my work in blueprints and my team does all of their work in blueprints.
Everything is going fine until we came across the problem that for an item crafting system for an RPG we need a way to get all children classes of a blueprint class.
Basically my jr scripter created the core setup for the crafting system by creating a BP_masterCraftingRecipie class from the actor class. It holds a struct with all the information such as an unlocked bool, class to spawn, barsIron needed int, craftinLvlRqd int etc.
So he went ahead and created about 50 children classes that all inherit from that master class for all the items we currently have craftable.
Then onto me, the GUI guy. So I set it up so that we have an unlocked and locked “recipie list” in scrollboxes. Obviously I dont want to manually add hundreds of widgets and the logic associated with them 1 button by 1 button at a time. I’d rather just basically
**
pseduo BP script**
OnConstruct()
{
RecipieArray ChildClass = GetAllChildClasses(BP_masterCraftingRecipie)
forEach(ChildClass)
{
if(Unlocked == true) { AddToChild(ScrollBoxWidget, RecipieButton) }
else { AddToChild(ScrollBoxWidgetLocked, RecipieButton) }
}
}
And for the recipie button widget it would go something like
**
pseduo BP script**
forEach(ChildClass""...
Break craftingRecipeStruct & getRecipeName
set ButtonText = getRecipieName
So that basically everytime the game is run, it iterates through every BP child class of BP_masterCraftingRecipie, gets the “recipieName” member of the strut variable it holds (inherited from the master class) set the button text to it (this widget is just a sizebox, button, and text on the button).
Then when the crafting screen is opened, it adds each recipie button widget with its respective name and when its clicked it gets that specific childs class struct info and displays it.
So where I’m stuck on, is how to get all the children class so that I can set the button names (to start, later to get all the rest of the structs data).
Since my team works purely in BP and I work 99.9% in it, I thought a Function Library c++ class with BlueprintCallable would be best or BlueprintPure i guess doesnt matter. I’ve seen a couple examples online I’ll have to test, but since I’m so new to the API and to C++ (only C# and JS experience before UE4) but any tips on getting the children class of a master parent class when none of them are in the world would be great. Any tips at all would be great.
I’m willing to send the project to anyone thats really intrested in helping.
Heres a picture of the prototype screen setup I came up with to better illustrate what Im trying to do, instead of manually adding each recipie as it gets created (plus just the fact of doing it manually) i want to future proof it by using the struct data and child widgets, while retaining BP functionality for my team and I.
Thanks.
Edit: Heres another one, of how I’d build the array of recipes obviously i’m going to need a C++ function that is Blueprintcallable or ""pure.
So far this is all I can find, I’ll do some playing around with it and see if it can be added to a function library and be callable. But my UE4 APi and CPP knowledge is so low, its almost unreadable
FClass* FClasses::FindClass(const TCHAR* ClassName) const
{
check(ClassName);
UObject* ClassPackage = ANY_PACKAGE;
if (UClass* Result = FindObject<UClass>(ClassPackage, ClassName))
return (FClass*)Result;
if (UObjectRedirector* RenamedClassRedirector = FindObject<UObjectRedirector>(ClassPackage, ClassName))
return (FClass*)CastChecked<UClass>(RenamedClassRedirector->DestinationObject);
return nullptr;
}
And something like this obviously only returns the BP_craftingMaster since its hidden in the level.
I take it the code above searches through all the classes and looks for any that point to the ClassName parameter? I’ll need to figure out how to make it BP callable and return a TArray
Edit: I found this much simpiler attempt, might have a go at playing with its statments anyone know if its viable? I’ll play with it later but it looks like somone checking for stuff already in the level and thus accessable.
void AMNCharacter::CheckForInteractables(){
TArray<AActor*> ThingsImTouching;
GetOverlappingActors(ThingsImTouching);
for (AActor* Thing : ThingsImTouching)
{
if (Thing->GetActorClass() == AMNPickup)
{
}
}
}
Last edit before I stop googleing for now: https://answers.unrealengine.com/questions/8687/iterate-all-blueprints-derived-from-a-class.html
that is exactly my problem, trying to populate a GUI with classes derived from a master class. And this answer seems perfect, does anyone know whats been long depreciated and needs replacing, I should be able to figure out how to return an array of all the classes it finds this way, its alot more readable than what I’ve found so far, but its from 4.3
FAssetRegistryModule* AssetRegistryModule = &FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
TArray<FAssetData> AssetData;
FARFilter Filter;
Filter.ClassNames.Add( UBlueprint::StaticClass()->GetFName() ); //get blueprints
Filter.PackagePaths.Add("/Game/Blueprints/RoomModel"); //from location
AssetRegistryModule->Get().GetAssets(Filter, AssetData);
//AssetRegistryModule->Get().GetAssetsByClass(Class->GetFName(), AssetData);
for (TArray<FAssetData>::TConstIterator PkgIter = AssetData.CreateConstIterator(); PkgIter; ++PkgIter)
{
FAssetData Asset = *PkgIter;
UBlueprint* BlueAsset = Cast<UBlueprint>(Asset.GetAsset());
if (BlueAsset->ParentClass == ARoomConnection::StaticClass()){
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, Asset.AssetName.GetPlainNameString());
}
}