How would I go about getting a reference to a UClass of a blueprint class in C++ if I’m outside of the constructor and not able to use the Constructor helpers.
But I just can’t find the proper string to use as the class name itself when trying to use this. I just can’t figure out the logic behind the naming conventions.
if you have a reference to the blueprint, you can just use the “GeneratedClass” member which gives you the correct UClass.
Is there any reason why you need to construct a UClass from a string?
Well, I just need a class reference in some C++ code because I’m working on code that’s too complicated to write in blueprint. I have a lot of C++ and Blueprint interop going on.
It’s kindof the same reason, when you create a shooter game in C++, GameMode retrieves the blueprint pawn class:
That’s what I’m doing now since I have no other way to do it. I initialize the class reference from the C++ constructor, or I can create the class reference in Blueprint itself in the editor.
This adds a bit of tediousness to the thing I’m trying to do in this case since I now have to have all these properties instead of just sitting down and writing some code. It’s basically something that’s too complex for me to do in Blueprint right now. Ideally I’d be doing this in blueprint, but in order to get my game out the door, I decided to keep things simpler and do it in C++ since I don’t have to find ways to expose functions and come up with other complex design decisions. I’m the sole programmer so I don’t have artists who can’t do C++ on my team right now.
As you seem to be adamant on using hardcoded strings, you can do what they were doing in the Answer Hub answer:
FindObject<UClass>(ClassPackage, ClassName)
Where if your blueprint is named: ‘BP_MyBlueprint’
The ClassPackage is the Blueprint name (i.e. ‘BP_MyBlueprint’)
and the ClassName would be ‘BP_MyBlueprint_C’
All blueprint classes have the ‘_C’ appended.
Again, I would recommend actually using the TSubclassOf method, as you really are fighting how the engine works.
Do I need to use the full name of the blueprint? Most things aren’t just named with the display name you see in the editor. There is usually a whole path. I can try these combinations some more when I get home.
I usually use TSubclassOf to store class references themselves. What did you mean by I’m fighting how the engine works? I thought this is normally perfectly fine since you can get class references in constructors. I just wanted to do it outside of a constructor.
To use another coding example, it’s like using magic numbers in code.
Yes it works in practice, but is quite nasty and frowned upon.
This is the same, hardcoded strings to get the class references is more nasty and inflexible compared to having a reference set on a blueprint.
I say your fighting the engine, because you’re trying to work around the issue instead of using it the way it’s designed.
It makes me cringe as a coder. XD
And it is most likely the full path for the package name.
It’s probably something like: ‘/Game/Blueprints/BP_MyBlueprint’
Well, what I’m basically doing is scripting something for a very specific level in my random level generator. Normally, something scripted for a very specific level would be done in blueprint, but my level generator is still in an early stage where I can’t really do low level stuff with it in blueprint. It’s all in C++.
I have a lot of things in my random level generator configurable through blueprint with UPROPERTY and other things. And I have these objects called PostPassEvent objects that let me do some really level specific custom behavior that can’t be done as easily with the generic system I have in place. This is used for puzzles and other very specific things that only that one level will require. My blueprint object has a class reference to a PostPassEvent object. This PostPassEvent object is actually doing some custom behavior in C++ though.
So, for example, on level 2 I need to spawn a locked door from an area that is farthest away from the starting area in my area graph, and then spawn a key that is somewhere else. This should be done in blueprint, but I haven’t exposed blueprint event methods for this kind of thing, so my scripted events have to be done in C++ for now.
Spawning a locked door an key puzzle can potentially be generic enough to be reusable all over the place, but a very specific example is on level 1, traversing my area graph and making all areas branching off of the shortest path between the start and exit have locked doors until a certain objective is completed. This will allow players to quickly get to the main objective in a linear level, and then suddenly the game becomes nonlinear and lets them backtrack and explore once they are no longer noobs and have completed their first basic objective.
Doing this in C++ and not blueprint isn’t the best, but it works and lets me get the game out. I have to cut corners in just the right places or else I’ll be stuck working on this game for years.
Believe me, I care about writing high quality code
What exactly is the use case? Might be able to help since we do a lot of this stuff outside constructors.
If you are just looking for a specific type of actor during or after BeginPlay() you can always just search for it with ActorIterator:
// iterate through all world actors
for (TActorIterator<AInteractiveActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
{
AInteractiveActor* actor = Cast<AInteractiveActor>(*ActorItr);
if (actor)
{
// do something with the interactive actor
}
}
Oh wow this is kinda old, I actually figured this out a while ago. Here’s a sample code snippet.
TSubclassOf<(C++ Base Class goes here)> SomeBlueprintClass = LoadClass<(C++ Base Class goes here)>(nullptr, TEXT((BluePrintReferenceNameGoesHere)));
An easy way to obtain the blueprint reference name is to right click on the blueprint in the editor, and copy reference.
Then paste it and you get some text. You add _C to the end for some reason, probably C for Class. And it works. Not sure why this wasn’t documented better.