Get UActorComponent Class Reference from String

Gday All,

So I am reading in data from SQL and everything is as strings, works well for everything except I need to convert one of the strings into a Actor Component class reference,

I have spent about four hours today going back and forth and cant get it to work, this is my current code

.cpp

UActorComponent * USRGameInstance::GetClassFromString(FString compClassName) { UActorComponent* foundClass = FindObject(ANY_PACKAGE, *compClassName); return foundClass; }

.h

UFUNCTION(BlueprintCallable, Category = "Component") UActorComponent* GetClassFromString(FString Name);

Which is giving me a node in blueprint, but the node is returning None :frowning:

Which I am guessing either has something to do with the string I’m passing in, or that the object isnt loaded, then I would need to use LoadObject, but have been banging my head against that for 2 hours with no success :frowning:

Hoping the community can help me out :slight_smile:

First of all you will need to use FName instead of FString (engine APIs will force you to convert one way or another at some point). FName is type design to store names in hash maps allowing to faster finding and comparison between them and faster processing as result. All string IDs in UE4 are stored in FName and it recommended to you to do that too.

Components are not stored by name, but subobject does, so you might have better chance with it, components in actors are registered as subobject in C++, not sure if this works with components set in blueprint but it’s worth a try. It’s design to work not only with components but any object attached to the other object, so function return universal UObject*:

Other option is use tags as there option to get components that have them, you may try to utilize this too

Gday , Thanks for that but unfortunately GetDefaultSubobjectByName returns a UObject, s o even if if found the object it wouldn’t pass as a Actor component :frowning: but as it turned out it didnt work anyways :frowning: I changed my FString to FName for FindObject, but then it says that it cant convert FName to TCHAR, so I changed it to TCHAR and now its telling me;

Error		Unrecognized type 'TCHAR' - type must be a UCLASS, USTRUCT or UENUM
 

I have NULL as the first argument as it says in the doco link text
So something weird going on there, I trolled through the UActorComponent functions but none of them accept a FName or anything similar so am a little stumped now :frowning:

After doing some more reading I think I can use the Asset Registry to get what I need but am coming up with LNK2019 error when trying to build the example code, so have posted a new question

So after some help from SamWise, I managed to get Asset Registry to work, but I still can only get a UObject back which if I convert to class just returns Blueprint, not the actual class reference I am after;

Heres my code as it stands now
UObject* USRGameInstance::GetClassFromString(FName classPath, FName className)
{
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(“AssetRegistry”);
TArray AssetData;
FARFilter Filter;
Filter.PackagePaths.Add(classPath);
Filter.PackageNames.Add(className);
//Filter.ClassNames.Add(UActorComponent::StaticClass()->GetFName());
AssetRegistryModule.Get().GetAssets(Filter, AssetData);
UObject* retObject = AssetData[0].GetAsset();
//UClass* retClass = retObject->GetClass();
return retObject;
}
the object has the correct path and everything just when converting to class it returns the wrong class :frowning:

Think I will get some sleep and have another go at this tomorrow, hopefully someone might have a solution for me by then :slight_smile:

FString is secretly TCHAR array and you can access TCHAR that it has inside by putting asterisk ( * ) before variable name. So let say you got FString SomeName; you just do *SomeName and there oyu go your FString becomes TCHAR… because FString stores string as TCHAR inside it self, it’s array of TCHAR you can even do SomeName[0] to access individual TCHAR characters ;p

It sounds like you never heard of casting. It returns UObject* because it can contain any object, asset, actor or actor component etc, anything. in most object oriented programming languages the type of variable need to be most common denominator of all object it potentially will contain, because it can not contain anything lower then that from class inference tree, and UObject* is the lowest you can get, this type can contain any UE4 object (or else you got non-UObject object).

You also need to be aware that pointers (types with * at the end) only points to the object, they don’t change type of it, if you get UObject* you access it as a UObject but it still gonna be USceneComponent or class above (whatever component you talk about) in memory and you can cast it to any other inherent class type using Cast function. So you can do this:

Cast(GetDefaultSubobjectByName(NameString));

This will cast UObject* to USceneComponent*, if you object won’t be related to USceneComponent it will return null. Now this function is part of UE4 APIs is specially made for UObject pointers, there more native ways to cast in C/C++ you can read about it here:

But if you use cast any UObject pointer you should use Cast function, it makes it a lot more cleaner as with native casting you would end up doing a lot of class checking.

Please try using GetDefaultSubobjectByName before attempt to use AssetRegistry. People who use AssetRegistry as ultimate solution for everything are usually people who dont see full picture of UE4 outside of content browser and blueprints. AActor contains all data you need, it has full component information you don’t need to get anything else, you just only need to find away to get that data from the object you already have.

Gday ,
Yeah I do know about pointers and C storing strings as arrays of characters or at least I did 20 something years ago at Uni when I was good with C+, cant remember if it had one plus or 2 pluses back then but remember getting distinctions for that stuff lol but it has been a long time. and about 10 other languages since the :slight_smile: but it is all coming back slowly :slight_smile: and the subtleties of Unreal weren’t involved I did try casting the object but wasn’t having any luck, I’ll go back to it and give it another whirl once I get some more sleep things might seem a whole lot easier, will let you know how I get on :slight_smile: at least the asset registry stuff gave me a better understanding of how Unreal stores asset data and reminded me about the whole pointer thing :slight_smile: