Blueprint component reordering

I do not know if this has been implemented in 4.12, but in my current project on 4.11, I’m doing a lot of stuff with blueprints. It’s quite annoying when I accidentally move one of my components trying to just select it and end up parenting it to a different component. It seems like you should be able to move components between each other, as well as parent components to other components. Right now, when you drag your component and try to position it between two other components so as to move it, it just parents to the one the cursor is slightly over.

1 Like

It’s a really tight area to work with; but if you look at the pop-up tooltip when moving a component, it will say something similar to “Move before this selection” or “Move after this” when at the top or bottom of another component. I noticed this in 4.10; not sure if it existed before that point.

I definitely agree that a bit more delineation would be nice though.

That doesn’t show up for me. And to be clear, I’m talking scene components, not actor components. Are you able to do it with scene components?

Are you referring to doing so in the World Outliner? I was referring to Actor Components with my answer though.

I’m referring to the list of components in the Blueprint editor.

That does not show up for me either. The only tooltip that comes up when trying to move a components has to do with attaching it to another component. Could you please outline the steps to make it easier to understand. I have a list of components that are numbered and I would like them to be arranged in ascending order.

im also dealing will plenty of components that i would love to reorganize to keep my sanity. eighter by draging them around like the users above want, or a way to sort them alphabetically

I would like to see this, as well. It’s a little crazy we can’t reorder components within a blueprint.

1 Like

When adding a component to an actor, it appends the component to the list of components (or to the list of child components if added as a child somewhere), so it will be added at the end. If you need to re-order the component, you will need to detach any existing components from their parent (using the tool-tip option of dragging to a new component root). Then re-add them in the desired order. This is a pain for actors with a large number of components, but then again, having a large number of components on actors is not advised for performance reasons anyhow.

This has nothing to do with a component limitations and/or efficiencies within a Blueprint. I totally disagree with the statement about using a “large number of components” being bad for performance–it’s all relative of course. Blueprints with 20+ components (however simple/complex) are a regular occurrence, parented or not. The fact that you can’t simply move components up or down within a list, becomes cumbersome after only 10 components. Always appending the list regardless of the component selected, is well…clunky. Not having the ability to move them up or down the list afterward, is just ridiculous. (see Data Tables). Love Blueprints, but I’ve been wanting this for years.

9 Likes

6 years and still nothing

3 Likes

Bump - I’m working on a BP with 30+ components and it sure would be nice to have a way to reorder them or otherwise keep them organized

Unreal is officially ■■■■■ Made - problems like this started the Spanish Inquisition

Would like to be able to sort components too…

I think the problem in the engine code is this method:

void SSubobjectEditor::UpdateTree(bool bRegenerateTreeNodes /* = true */)
{
	check(TreeWidget.IsValid());

	// Early exit if we're deferring tree updates
	if (!bAllowTreeUpdates)
	{
		return;
	}

	if (bRegenerateTreeNodes)
	{
		// Obtain the list of selected items
		TArray<FSubobjectEditorTreeNodePtrType> SelectedTreeNodes = GetSelectedNodes();

		// Clear the current tree
		if (SelectedTreeNodes.Num() != 0)
		{
			TreeWidget->ClearSelection();
		}
		RootNodes.Empty();

		if (UObject* Context = GetObjectContext())
		{
			ensureMsgf(FModuleManager::Get().LoadModule("SubobjectDataInterface"), TEXT("The Subobject Data Interface module is required."));

			USubobjectDataSubsystem* DataSubsystem = USubobjectDataSubsystem::Get();
			check(DataSubsystem);

			TArray<FSubobjectDataHandle> SubobjectData;

			DataSubsystem->GatherSubobjectData(Context, SubobjectData);
...
}
...
}
}

Its sad that any change will not persist.
I wrote the following editor code to Sort Components Temporarily:

if (UToolMenu* EditorContextMenu = UToolMenus::Get()->ExtendMenu("Kismet.SubobjectEditorContextMenu"))
{
    EditorContextMenu->AddDynamicSection("MyGame", FNewToolMenuDelegate::CreateLambda([](UToolMenu* InMenu)
        {
            USubobjectEditorMenuContext* ContextObject = InMenu->FindContext<USubobjectEditorMenuContext>();
            if (ContextObject && ContextObject->SubobjectEditor.IsValid())
            {
                FMenuBuilder MenuBuilder(false, nullptr);
                USubobjectEditorMenuContext* SubobjectEditorMenuContext = InMenu->FindContext<USubobjectEditorMenuContext>();

                auto& Section = InMenu->AddSection("MyGame", NONLOCTEXT("MyGame"));
                Section.AddMenuEntry(
                    "SortByName",
                    NONLOCTEXT("Sort By Name (Temporarily)"),
                    NONLOCTEXT("Sort components by name temporarily (Impossible to make those change last for the moment.)"),
                    FSlateIcon(),
                    FUIAction
                    (
                        FExecuteAction::CreateLambda([SubobjectEditorMenuContext]()
                            {
                                if (auto SubobjectEditor = SubobjectEditorMenuContext->SubobjectEditor.Pin())
                                {
                                    if (SubobjectEditor && SubobjectEditor->GetObjectContext())
                                    {
                                        if (auto BlueprintGeneratedClass = Cast<UBlueprintGeneratedClass>(SubobjectEditor->GetObjectContext()->GetClass()))
                                        {
                                            auto TreeWidget = SubobjectEditor->GetDragDropTree();
                                            TArray<FSubobjectEditorTreeNodePtrType> SelectedItems;
                                            TreeWidget->GetSelectedItems(SelectedItems);
                                            for (auto& SelectedItem : SelectedItems)
                                            {
                                                auto& Children = const_cast<TArray<FSubobjectEditorTreeNodePtrType>&>(SelectedItem->GetChildren());
                                                Children.Sort([BlueprintGeneratedClass](FSubobjectEditorTreeNodePtrType Node1, FSubobjectEditorTreeNodePtrType Node2)
                                                    {
                                                        return Node1->GetComponentTemplate()->GetName() < Node2->GetComponentTemplate()->GetName();
                                                    });
                                            }
                                            TreeWidget->RequestTreeRefresh();
                                        }
                                    }
                                }
                            }
                )));

            };
        }));
}

Cheers

1 Like