Download

Single actor with multiple mesh components

I am creating an actor that is built from several different meshes. If it’s required, I can make each mesh an actor, but I’d like to avoid that (I can go into the reasons if needed).

The reason I don’t just use my 3D modeling software to combine the meshes into a single mesh is that this is a procedural construction – I don’t know which pieces to use until run-time.

So, my approach is to create a C++ class derived from Actor and then (in the constructor), create the mesh components and attach each one like so:



// Create the RootComponent mesh here as usual...
RootComponent = ...

for (...)
{
    // Get these strings from an array based on some conditional code
    mesh_asset_name = ...
    mesh_component_name = ...

    ConstructorHelpers::FObjectFinder<UStaticMesh> mesh(mesh_asset_name);
    mesh_component = CreateDefaultSubobject<UStaticMeshComponent>(mesh_component_name);
    mesh_component->SetStaticMesh(mesh.Object);

    mesh_component->AttachTo(RootComponent);
}


Am I “abusing” the FObjectFinder by doing this? I guess my main concerns are:

  • the [FONT=Courier New]FObjectFinder declaration isn’t static
  • I’m not saving the [FONT=Courier New]mesh_component pointer (it’s just a local in the scope of the constructor)

I don’t really understand why that declaration is usually static. Performance, maybe? I kind of always thought that static local variables were something to avoid, when possible.

Are these like animation states? Are the meshes like “idle”, “damaged”, and “dead”?

If yes, can you use the State Machines system for this situation at all in Blueprints?

If I’m not reading the situation right, let me know and I’ll dig into your code better, but upon an initial pass this was my first glancing suggestion.

No, but close… It’s more like I’m building a house mesh and I choose a random roof, door, windows, walls, floor, etc… But it all ends up being one actor.

OH ok I get you, I mean it’s sort of the same thing. I’d still highly recommend delving into the States Machine system for it.

But also I’d look into it maybe being one actor but multiple character classes with multiple states all under the parent “house”. Then if your door character has 5 animation states (red, blue, green, yellow, pink) you can use the State Machines system to seamlessly transition between your meshes instead of like you eloquently put it “abusing” the FObjectFinder which would REALLY weigh down the scripts.

Generally, the way I have found C++ to work in Unreal is if it starts to get more complicated than what I learned in high school then there’s a better way.

I don’t see anything particularly wrong with what you’re trying to do. Store each meshcomponent in a TArray of meshcomponent pointers so you can do something with them if needed. I’ve not used the FObjectFinder syntax myself but if that works, then why not?

a mesh component is just a mesh that is part of the object. Nothing wrong with making many of them per actor. Shootergame does that for the arms and third person meshes for instance.

Thank you guys for the replies. Lindsay, there’s not really any “state” involved. I choose the components at as soon as the actor is created, so, it all happens in the constructor. After that, the actor just is what it is for the duration of the level. I guess there’s a chance that I might add “damaged” states to it eventually, but I see that as kind of tangential to what I’m trying to accomplish.

So let me say that the reason I’m asking is that my performance is not very good at all, which leads me to believe that I’m bending the rules in a way that I shouldn’t. I boiled the experiment down to two simple scenarios.

Scenario 1:
I create a plain old Actor class with just one mesh component with 12 triangles. I can spawn around 300 of these and not see any real slowdown. It runs at 35+ fps.
12 triangles * 300 actors = 3600 triangles

Scenario 2:
I create my fancy Actor class with multiple components. Each actor has 12 mesh components and each component has about 6 triangles. If I spawn just 50 of these, the frame rate slows to 10 fps!
6 triangles * 12 components * 50 actors = 3600 triangles

In both of those scenarios, the raw number of triangles is absolutely nothing for a modern GPU. But something about the second one brings UE to a crawl.

Hmm… Typing this out made me realize that I should do a third scenario – I should try making each component a separate actor and then just “parent” them.

I’m pretty sure you’re not abusing FObjectFinder. I think the reason it is usually declared static is just that this means its construction will only execute the first time you create an actor of the given class. This means the actual locating of the resource isn’t repeated needlessly when every instance of the actor uses the same resource. The performance gain is presumably tiny and anyway only affects initialization time.

As to your runtime performance - having more components will introduce an overhead, but it should be nothing severe enough to explain the numbers you give. Your meshes aren’t configured to use complex collision by any chance? You’d really need to profile it to find out where the time is being spent. First step would be to type ‘stat unit’ into the console while you’re running to see if it’s the game or rendering thread that is the bottleneck.

Hmm, this is a wild guess, but I’d suspect collision shenanigans here. There was a big slowdown I had a while back where my actor was set to merge collisions (might have been instanced static mesh based, cant remember now), the merging of collisions basically made it crawl.

So its likely there’s a checkbox somewhere you havent checked, or have checked when you shouldn’t, which seems to be the way with UE :slight_smile:

Great guesses, kamrann and zombapup… It turned out to be the lighting. I had a few light sources that I added long ago and forgot about, but didn’t realize that they were all “sun” lights and were all set to cast shadows. Just unchecking the “cast shadows” box on them brought the FPS back to 60 in all tests.