Adding components to actor based on sockets in mesh

Hi,

I have a C++ subclass of AActor called AAircraft which in it’s constructor does the following:

AircraftMesh = CreateDefaultSubobject<UStaticMeshComponent>(FName("AircraftMesh"));
AircraftMesh->SetupAttachment(RootComponent);

I then have some blueprints created as a child of AAircraft, for eg BP_Aircraft_Big, BP_Aircraft_Small. Each of these blueprints assigns a static mesh to the AircraftMesh component.

These static meshes have various sockets in them. What I want to do is find all sockets on the StaticMeshComponent where the name contains (for example) “light”, and then use CreateDefaultSubObject to create a new component attached to that socket. I want these components to be manipulatable in the components tab when editing the blueprint, and selectable when using the blueprint Viewport - just as with any other component.

Of course, in the C++ constructor, if I call AircraftMesh->GetAllSocketNames(), it returns an empty list because the static mesh hasn’t been applied to the StaticMeshComponent. If I call it in PostInitializeComponents it returns the socket names, but then I can only add the components using NewObject which means they don’t show up in the components tab in the Blueprint editor, making them harder to edit.

How do I do what I’m trying to do? I’ve been fumbling around with the FObjectInitializer and the archetype stuff for two days now and got absolutely nowhere.

Thanks for any help.

Hi David Gundry,

The best way to do what you want to do is to create your components that you want to attach in the constructor using CreateDefaultSubobject, like you’ve been doing, then override OnConstruction in your actor. In there, you can check to see if your static mesh component has a mesh. If it does, then you can attach your other component(s) to the mesh component using the socket name.

The problem with that is that I don’t know how many components I want to created until I have access to the sockets. The mesh might have 0 relevant sockets or it might have 100.

Hi David,

If you’ll be dynamically creating components, then you need to use NewObject. To have the components show up, you need to set the component’s CreationMethod to EComponentCreationMethod::UserConstructionScript (assuming you’re doing this in OnConstruction) and you’ll need to keep a serialized reference to the component so that it will not be cleaned up by the engine. (Something like an array of components where the array is marked with UPROPERTY would be fine.)

Hey thanks for that. Components created this way aren’t able to be modified in the blueprint editor, though, as they are only created when the actor is placed or spawned. I need these to exist on the archetype, basically.

Hi David,

Looking into it, you’re going to have to modify the CDO not the archetype to have components show up in that list. There will be a different CDO per-blueprint, which I’m guessing will be okay for your situation.

Hi David,

In a test where I created a variable number of static mesh components based on an integer property, I was modifying it in OnConstruction. I had to recompile the blueprint to get the component list to update properly, though. Also, it is important to remember to destroy the old components if the new count is less than the old count.

Where’s the correct location to modify the CDO? Is it inside the constructor, or can I do this through a custom editor window or something?

Alright I’ll take a look at adding components to the CDO in OnConstruction and see how that works. Thanks!