Adding components and modifying properties of UBlueprint asset?

I’m trying to add a whole bunch of static mesh components to a UBlueprint asset. I have a UBlueprint pointer.

Also needing to set the static mesh that’s used by each of them, their render settings (shadows, etc), collision, and so on. Would be super handy to be able to modify some properties that come from the C++ class that the blueprint in question inherits from.

It seems like components are added in the blueprint editor window via SSCSEditor, which is some Slate voodoo and totally off-limits to my random C++ code.

Any ideas?

EDIT: To give some more context, this is for an editor plugin that allows our artists to swap out actor instances in the level of a specific base class (and which has static mesh components added to it dynamically) by automatically creating a blueprint asset that represents one of the objects, setting up the same data (inc. dynamically-added components), and replacing the selected actor instances with instances of this newly-created blueprint.

It looks like it’s only possible from within SSCSEditor? That’s a tough widget to get! I’ve gotten down to SLevelEditor, but can’t seem to retrieve this particular widget. Not even sure if that’s the best way, however.

It sounds like you just need the functionality provided by the Blueprint/Add Script button that shows up in the details panel for a selected actor, but to control programmatically which actors to apply it to?

You can invoke this very easily through FCreateBlueprintFromActorDialog, but presumably you won’t want a dialog popping up for each actor. You can see though in CreateBlueprintFromActorDialog.cpp that it is basically just calling FKismetEditorUtilities::CreateBlueprintFromActor(). If you need more control over the blueprint, this class provides some other useful functions, such as AddComponentsToBlueprint().

Hi Kamrann!

I’ve actually already gone down this path - I’m using my own version of FCreateBlueprintFromActorDialog so I can put in my own delegates and handle things where I wish. The last part I’m having trouble with is adding components to my blueprint asset.

My static mesh components don’t come through when using CreateBlueprintFromActor, presumably because they’re added dynamically rather than via AddDefaultSubobject. When I invoke FKismetEditorUtilities::AddComponentsToBlueprint and pass in the mesh components I grab from the C++ actor that the blueprint is based off, they’re all added, but the pre-existing root component is ignored, and a new one is created that has no transform. I’ve tried manually adding the C++ actor’s root USceneComponent again via AddComponentsToBlueprint, and this works better (the root component is no longer made one of the static mesh components), but it’s still not ‘right’ (there is no way to move the root component, and it has no transform).

Is there a way to add components to the blueprint while respecting the pre-existing root component?

EDIT: There are also no visible components until I recompile the asset manually. When I do that, I’m spammed with one of these per component added:


[2015.09.18-00.19.28:471][765]LogBlueprint:Warning: USimpleConstructionScript::FixupRootNodeParentReferences() - Couldn't find native parent component 'SceneComponent' for 'StaticMeshComponent_534' in BlueprintGeneratedClass 'REINST_MyBlueprintName_Blueprint_C_41' (it may have been removed)

And this at some point:


[2015.09.18-00.19.28:481][765]LogActor:Warning: MyBlueprintName_Blueprint_C /Engine/Transient.World_2:PersistentLevel.MyBlueprintName_Blueprint_C_1 has natively added scene component(s), but none of them were set as the actor's RootComponent - picking one arbitrarily
[2015.09.18-00.19.28:507][765]PIE:Warning: Warning AttachTo: '/Engine/Transient.World_2:PersistentLevel.MyBlueprintName_Blueprint_C_1.SceneComponent' cannot be attached to itself. Aborting.

Okay. I guess it’s possible that FKismetEditorUtilities::AddComponentsToBlueprint is only intended to be used when first constructing a blueprint that doesn’t have any existing components. I haven’t used it myself.

Still, it seems strange to me that your static meshes aren’t getting added automatically. Where and how did you create the static mesh components for the actor? If you just select one such actor and use the Blueprint/Add Script button, does that also result in a blueprint that is missing the components?

For anyone trying to solve this, the below code seems to work for me in 4.19:




//Creating a blueprint

UBlueprintFactory* Factory = NewObject<UBlueprintFactory>();
IAssetTools& AssetTools = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools").Get();

UObject* Object = nullptr;
Object = AssetTools.CreateAsset(
NewFileName,
NewFilePath,
UBlueprint::StaticClass(),
Cast<UFactory>(Factory)
);

UBlueprint* Blueprint = Cast<UBlueprint>(Object);

// Adding a Hierarichal Instance Static Mesh, but I believe this can be any actorcomponents (Not tried)

USCS_Node* Node = Blueprint->SimpleConstructionScript->CreateNode(UHierarchicalInstancedStaticMeshComponent::StaticClass(), TEXT("HISM"));
Blueprint->SimpleConstructionScript->AddNode(Node);
FKismetEditorUtilities::CompileBlueprint(Blueprint);



Hope it helps.

Regards
Raz

2 Likes