When dropping meshes into a level at design time, they will be spawned as “StaticMeshActor”, right?
Now what if I would like to instantiate items using different classes than “StaticMeshActor”. How can I force UE to use the class I need?
I know I could encapsulate meshes in blueprint classes at designtime, but what if I would like to avoid this?
The background is this: I am using UE for architectural visualization and have different assets like chairs, tables, doors, windows and so on, all already added at designtime before I start programming the level, thus theses assets are not encapsulated in blueprints. But I would like to add functions, properties, member variables, use inheritance, overriding and so on to have these items to e.g. respond differently to messages (interfaces).
I one word: How do I make assets being added at design time to be instantiated from classes I want them to belong to?
I think you still might want blueprints. You can have a class that has two main code areas
Materials and variables in the construction script
Interaction in the event graph.
If you’ve laid out your map by just dragging meshes into the scene, you can select a group of them and use
which will give you a new BP which inherits from your main class.
Or, you could set things up so that you just drag a copy of your empty BP into the level, tell it which meshes to use, and go from there.
The main BP can hold all the interaction code, including timelines etc, so you don’t have to write anything once you get it right ( or not much ).
You could also possibly incorporate editor utility widgets to help you, but that’s not really my area
PS: If you want a totally integrated solution, where the whole environment is angled towards archviz, then a marketplace plugin is probably the way. Although I can’t find a appropriate one right now…
However I still don’t see the way to go. Converting a mesh from within the the editor always results in a NEW blueprint, right? If it would be possible to convert it to an existing class, then I would have what I want.
The levels I get for programming all are ready-made and definitely StaticMeshActors, so dropping blueprints is no way, everything is already there.
So still for me the question is: How can I assign the classes I have designed once to the meshes in the level?
Or which other way/system is the way to go to assign functionality and behavior to the items in the level?
How about actor components? They support inheritance, interfaces, run functionality, fire dispatchers, expose per instance editable variables, know who their owner is, can be added to any actor at design time or dynamically. This way you do not touch anything in the scene, but instead add a component to any static mesh actor that needs to run logic.
@ClockworkOcean Thanks a lot! But however still this results in a new new Blueprint that causes useless overhead by generating empty blueprint(childs). The method you suggest derives a new class from my class, instead I simply want to assign my class.
So as far as I unterstand until now there is no chance to alter the class of a mesh at designtime when being dropped to the level editor, right? Actually this is something I don’t understand why this isn’t made possible.
@Everynone Yes, As far as I can see this makes it possible to implement what I want. Now I have to go one step further. As you wrote it is possible to add components add runtime. This is exactly what I need, but now I have one more request:
Assuming I want to dynamically add components at runtime I also need to determine WHICH component at runtime depending on the mesh I am actually dealing with. Think of a room with 50 tables and 50 chairs, all dropped into the level thus each of them being a StaticMeshActor.
Now it would be possible for me to set the “TAG” property of all tables to e.g. “table” and those of the chairs to “chair”.
When starting the level I would like to iterate all StaticMeshActors and then dynamically add actor components based on the content of the “tag” property but WITHOUT having a branch statement hardcoding the names that might occur in the “tag” property! Why?
Assuming I have 150 different kinds of assets in the level, all StaticMeshActors , meaning 150 different contents in the “tag” field, I don’t want to have to code something like “if tag == chair then add actor component of type chair_component”, if tag == table then add actor component of type table_component".
Instead I would like to add the components by using the content of the tag property like so:
AddActorComponent([tag_content])
Is this possible? This way it would be possible to decide WHICH component has to be added based on the content of the tag field.
The list is run-time dynamic btw. So yes, tag them first, run script (either run-time or design time → it’s a thing as well) to fetch them all and spawn components. Or laboriously add a bazillion comps by hand.
You could even take it further and associate tags with entries in a data table, not only can it hold a component class to spawn by tag, but also data sets / variants.
There’s also this:
But I’ve never used it. Not sure if applicable here.
Thanks again! Still I don’t get it, feeling sorry!
Assuming I have added a Tag “BPC_chair” to a StaticMeshActor, how can I use this string then to dynamically add the component “BPC_chair” to that mesh?
There will be a lot of ways to pull this off. First of all, you’d need to decide:
are you giving the components to static mesh actors in the scene by hand at design time (if you have a 100, that’s pretty feasible. 10k? - not so much)
or are you doing this fully dynamically run-time. This would only make sense if the scene was procedurally generated, which it isn’t, it seems.
I mentioned it above but I’ll mention it again, there are blueprint utilities where you create tools to automate a process like this, especially if the scope of the task justifies it. And if it does, it’s worth looking into subsystems - helps to fetch & operate on the actors in the scene.
and finally, one extra thing to consider if the hierarchy is complex and you need to filter objects efficiently:
But then you still need to probably pipe in some data into the comps (we still don’t know how complex this needs to be). I do not miss the UE4.xx times when components were second-class citizen; things become so much more flexible:
a Data Table might work better => actor Tags pull DT Row Names which gives you the associated Struct containing all there is to know about the object, including the component class. The main benefit - a DT can be edited inside and, most importantly, outside the editor. You could use your favourite spreadsheet to prep the data in a civilised way and import it.
Thank you so much! We are getting closer on what I need! Actually the scenes ARE sort of procedurally generated, because I get them completely readymade with many StaticMeshActors of very different kinds. The meshes are dropped into unreal engine from an external software, which enables to define tags for the assets that will then appear as tags in Unreal (not “component tags”). So this is (only) way to get the information WHAT an asset actually is, a chair, a bed, etc., and which component(s) has/have to be added.
Now in your code you have this:
Here is my problem: I would like to use the content of the tag DIRECTLY as selector for the component to add. If the asset has the tag “Furniture_Chair”, I would like to add the component “furniture_chair”, without having to maintain the map you have. This is because otherwise i have twice the work to maintain the list in the future. So what i actually need is the way to use a given string to
check if a component of that name is defined within unreal and then
add that component.
No naming “chair”, “table”, “flower”, “carpet” in the code, so to say a general function to add the component based on a given string.
Until now I could not find it, but I suppose this is because I am still almost a beginner in UE. That said, I really appreciate your help very much! Thank you!
You must associate the data somehow. UE cannot read minds. The actor has a tag → get data from the map (or DT which a map with a fancy interface). Not exactly sure I understand the ask. There’s little to maintain apart from telling the container which tag means which component - that’s what the script does. There’s nothing to maintain, not really.
Well, the tag itself IS the name of the component, it will be a naming convention! The tag, the string itself, shall tell Unreal which component(s) to add!
Sounds like you may need to look into the reflection system in C++. Almost certain BPs can’t pull it off without another system handling fName association. Seems risky, prone to issues. You mileage may vary, though, ofc.
Your tags would need to look like this, most likely:
The video you posted here shows exactly what I was missing! Now in the begin I misunderstood you, I read that this was DROPPED from 4.xx on, I did not really understand the tag component map. However to avoid having to maintain the map i finally succeeded using the tags to query directly for a actor component class name.
And you were right: Blueprints don’t - at least in UE 5.xxx - allow querying the names of the classes that are defined in a game at all. They do not expose the “reflection” system that is built in C++.
So the solution for me was to write a function in a C++ blueprint function library that takes a string (the tag) as a parameter and returns an “Actor Component Class” if a class with that name is defined in the game, otherwise null.
This then allows to add components defined by the content of the tags of actors, making it possible to dynamically add code and variables to actors at EventBeginPlay or at runtime. Of course such a string might also come from other sources, like data tables or http requests.
Below is how it looks in my Blueprint now, the C++ sources are attached also.
Thank you very much for pointing me to the right direction!
#pragma optimize("", off)
#include "MyBlueprintFunctionLibrary.h"
#include "UObject/UObjectGlobals.h"
#include "UObject/Class.h"
#include "Engine/Blueprint.h"
#include "Engine/Engine.h"
#include "UObject/UObjectIterator.h"
TSubclassOf<UActorComponent> UMyBlueprintFunctionLibrary::GetActorComponentClass(const FString& ComponentName)
{
// Add "_C" suffix for Blueprint classes
FString FullComponentName = ComponentName + "_C";
// Try to find the class by name
UClass* ComponentClass = FindObject<UClass>(ANY_PACKAGE, *FullComponentName);
// Check if the class is a child of UActorComponent
if (ComponentClass && ComponentClass->IsChildOf(UActorComponent::StaticClass()))
{
return ComponentClass;
}
// Return nullptr if the class is not found or not a UActorComponent
return nullptr;
}