Download

How would you give a blueprint a unique identifier with out manual entry.

The scenario is I want to populate the world with various NPC characters and enemies and have a unique identifier for each. All NPCs will be created from a base class and customized through blueprints in the editor.

My Initial Idea:
I don’t care what that identifier is (FGuid or FName or other) but I’d like to generate it when the blueprint is created in the editor rather than having to manually specify it for each entity I want to be unique. I’ve thought of various methods to actually create the unique identifier but the key goal is to generate it upon creation of the blueprint itself.

Another Idea:
I think I could possibly use the blueprint class name itself but am not entirely sure I want to use it. I would preferably like to use something like a generated number/string for the system rather than a flowery name given for human understanding. There is also a point that “some” of these will be spawnable and so will have a spawn identifier and an instance identifier when spawned. I know each object is given an identifier when spawned but it can be reused, so I would probably use that as the “instance” identifier. Is it possible to get the Blueprint Class Name for a Blueprinted object in C++?

I can’t help but think it would still be neat to do the first option, but am open to any suggestions that are floating around out there.

no responses to this is promising… I attempted to use the idea of using the blueprint name as the unique identifier but that never seemed to work as I could never find the blueprint name. So my query still persists… if you wanted to create a class based unique identifier how would you go about doing that? The purpose is to identify like types of items or entities like NPC’s, Identical items that need to stack in inventory, or even abilities.

In C++ you can call GetClass() on any UObject to get its (possibly blueprint) UClass. You can also use the returned UClass as a TSubclassOf<T> where T is the variable type where you called GetClass() on. For example



ACharacter * Char = ...;
TSubclassOf<ACharacter> BPClass = Char->GetClass();


I have good experiences with using TSubclassOf as a key in a TMap, for example for inventory management.

I have somewhat tried the GetClass approach but am never able to get the actual blueprint name. The additional issue is that I need a string of some sort because I need to construct a Unique identifier of unique identifiers to uniquely identifier a group of objects lol. Basically a group of items combined together will form their own unique identifier, but that same combination of items needs to form the same unique identifier somewhere else.

I would love an easy way for a designer to “generate” this when the class is created with out having to “think” or check documentation for a unique identifier. My current line of thinking is to do a direct edit of the editor itself to create some plugin or something that can create the identifiers… but that seems a daunting task and still looking for documentation on it…

I’m not sure what you mean by a unique identifier of unique identifiers, but TSubclassOf can be used to identify objects by class. For example if you have a C++ class UItem and a blueprint from that Potion. You create two Potion instances and call GetClass on both, the return values will be equal (== on the classes returns true). So for a group of objects you can identify which ones were created from the same class, is that not what you want?

About the class name, you can get the name of the blueprint class as an FString by calling GetName() on the class:



ACharacter * Char = ...;
TSubclassOf<ACharacter> BPClass = Char->GetClass();
FString BPClassName = BPClass->GetName();


Note that if your blueprint class is called Potion then BPClassName will have some value like Potion_C.

Why not use tags?

You can kind of think of it like a crafting system of sorts that where the final product’s identifier is the sum of the identifiers that produced the final piece. I got that part working. The core components will be blueprints so think of the case you are building a Bacon, Lettuce, and Tomato sandwich. The component blueprints would be UItems called Bread, Bacon, lettuce , and Tomato (with respective identifiers). When you construct a BLT the final identifier of the item would be Bread_Becon_Lettuce_Tomato. So I need FString or FName that contains a uniquely given name of the blueprint item to construct a derived name of the finished or crafted product, because you could just make a LT, a BT, or a BL instead of a BLT. I’d hate to have to create the “Bacon” blueprint and then give it the identifier Bacon again in the default properties for EVERY item I create, that could easily lead to forgetting to set that property, or mistyping the property. Ultimately I’m looking for a way to autopopulate the identifier with the name of the blueprint item to generate derived (in game) object identifiers. it may be a tall order…

I see what you’re trying to achieve. I assume making a different blueprint for each crafting result, like in this example a blueprint for Bacon_Lettuce_Tomato isn’t an option. You could concatenate their class names, so given you have a Bacon, Lettuce and Tomato instance where each class inherits from UItem. Get their class names using:



UItem * SomeItem = ...; // SomeItem is an instance of BP_Bacon, which is a blueprint that inherits from UItem
FString ClassName1 = SomeItem->GetClass()->GetName().ToString(); // Value will be BP_Bacon_C or something similar
FString CleanClassName1 = ClassName1.LeftChop(2); // Optional: Removes the last two characters, the _C


Then string concatenate the strings using FString::Append()



FString Result = "";
Result = Result.Append(ClassName1);
Result = Result.Append(ClassName2);
Result = Result.Append(ClassName3);


If order shouldn’t matter (Bacon_Lettuce_Tomato == Lettuce_Tomato_Bacon) you could sort the names alphabetically before appending them. Would using the combined name work for your purposes?

Hi Nisshoku,

Sorry for my absence on this. I have used a system for sorting the string to create a uniquely reproducible id (because the order of combined items shouldn’t matter, but the ID will) when you build the final product. Using the combined name is exactly what I am looking for but I feel I had some issue with it before (I’ll have to test it again to be sure).

I think you’re trying to do this completely the wrong way. I’ve done crafting systems before and simply used a unique integer ID value for each item and it worked just fine. For a “what makes this thing” lookup, you would simply have a recipe database which describes recipes based on inputs and outputs. So in my case I had an input inventory (and inventory is simply a growable array of Item ID and count pairs) which defined what went into the inventory, then an output inventory which defined what would be produced. That way you could have the same input item used in all sorts of recipes.

I just don’t see a scenario where having a concatenation of all the input ID’s would make any sense. Surely you’d also have to concatenate amounts too?

In reality my system had ItemID (with a unique integer ID and a count) and an Item (with the same ID value and things like name, description, icon etc). Essentially its all just a big database that has been normalized a bit and has the correct lookups/joins. No idea why you would complicate it with concatenations and the like.

Hello Zoombapup,

The System being built is not a crafting system (per-say), I simply used a crafting system as an analogy. The exact details I am not at liberty to discuss but needless to say I simply want a method uniquely identify a “blueprint class” of objects in a simi-human readable fashion that can then be used to create a string identifier of a player constructed object (again sounds a lot like a crafting system, which is why I used the analogy). Also the free nature of the system requires it to not use prebuilt recipes, it would defeat the purpose.

Beside that point the system works. The whole act of concatenating the identifiers of the components together to form the identifier of a final object I have all working. I just wanted an automatic method of producing the component identifiers in the editor without relying on someone else to manually enter the identifier of the components. However I am thinking I may not need to generate them via the editor but instead at run time based off the blueprint class name (such as setting it at Begin Play or when the object is spawned). In that case NisshokuZK would have the proper method of doing it (if it returns the blueprint class name and not the C++ class name, which is the trouble I remember having but I may not have been using the GetName() function… I need to check that and post my findings)

Woho Nisshoku, Okay the method works, I redesigned my system with your suggestion on calling the GetName() function. I think I did not want to utilize it because of the bazaar _C that get’s tacked on to it but with the addition of the chop command I am able to get the true Blueprint name which can now act as an Identifier.

Thank you!