Data Only Blueprints toggle

Could an option be exposed in Project Settings to toggle the default work of how a blueprint can open. If our team is making a lot of changes to blueprints, this would save a lot of extra clicks and time waiting for the window to switch modes.

It would be great if they could set a setting in Project Option and have the blueprints always open in Full Blueprint Editor.

It seems there are other people who wanted a feature like that for a while too…

Hi [mention removed]​,

Yes, I’ve also seen that this request has been asked in other cases. Will take a look into the development branch and see if by any change unreal devs have implemented this. If it still not implemented I’ll take a look and see how much work would it take to achieve that.

Would it be ok for you and your team to do a small engine modification if needed to apply that feature?

Best Regards,

Joan

Hi [mention removed]​

If needed I’m sure we can apply a patch to the engine. Would this patch also go into 5.7.2 or 5.8? We would like not to apply the patch every new version.

Also on the link I posted above, it does seem like some people submitted patches for this in the past. Although they might be outdated by now.

Hi Joan,

I will try the module out! Thank you!

Is it possible to put this in a PR so that it will get included in the engine? Native would be better, but even if it’s a plugin would be a great help.

Hi [mention removed]​

Yes, thank you for submitting this. I believe the change does not need to be a plugin like this, that forces everyone to do things differently, but it can be as described here:

This gives the users an editor option that lets them opt into that setting. A change like that would probably be easier to get accepted.

Hi [mention removed]​ !

After looking at the Unreal Engine development branch, it doesn’t seem like they’re planning to implement anything like this in either 5.7 or 5.8. At the moment, there’s nothing in the codebase that supports it.

I dug a bit deeper into the problem and found a way to achieve what you want without modifying the engine. I’ll share the solution below in case it helps you and your team. This only needs to live inside an Editor module.

As a quick test, I created a custom settings object under Editor Settings and added a TMap to specify which classes should always open in the full Blueprint Editor. You can remove that part if you’d prefer to apply the behavior to all Blueprints.

UCLASS(config=EditorPerProjectUserSettings, meta=(DisplayName="My Blueprint Editor"))
class EM_SC_56_API UMyBlueprintEditorSettings : public UDeveloperSettings
{
	GENERATED_BODY()
 
public:
	/** If a Blueprint is Data-Only and its ParentClass matches (or derives from) the key, it will open the whole Blueprint Editor*/
	UPROPERTY(EditAnywhere, config, Category="Overrides")
	TMap<TSoftClassPtr<UObject>, bool> ForceFullEditorForDataOnlyParents;
 
	virtual FName GetCategoryName() const override
	{
		return "My Blueprint Editor";
	}
};

With Unreal FAssetTypeActions_Blueprint class, you can react when an asset is open inside the Editor:

FMyAssetTypeActions_Blueprint.h

class FMyAssetTypeActions_Blueprint : public FAssetTypeActions_Blueprint
{
public:
	virtual void OpenAssetEditor(const TArray<UObject*>& InObjects, TSharedPtr<class IToolkitHost> EditWithinLevelEditor) override;
 
private:
	bool ShouldForceFullEditorFor(const class UBlueprint* BP) const;
};

FMyAssetTypeActions_Blueprint.cpp

#include "MyAssetTypeActions_Blueprint.h"
#include "BlueprintEditorModule.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "Modules/ModuleManager.h"
#include "MyBlueprintEditorSettings.h"
#include "Engine/Blueprint.h"
 
static bool CheckParentSuperclass(const UClass* Parent, const UClass* KeyClass)
{
	for (const UClass* C = Parent; C; C = C->GetSuperClass())
	{
		if (C == KeyClass)
		{
			return true;
		}
	}
	return false;
}
 
bool FMyAssetTypeActions_Blueprint::ShouldForceFullEditorFor(const UBlueprint* BP) const
{
	if (!BP || !BP->ParentClass)
	{
		return false;
	}
 
	if (!FBlueprintEditorUtils::IsDataOnlyBlueprint(BP))
		return false;
 
	const UMyBlueprintEditorSettings* Settings = GetDefault<UMyBlueprintEditorSettings>();
	if (!Settings)
		return false;
 
	for (const TPair<TSoftClassPtr<UObject>, bool>& Pair : Settings->ForceFullEditorForDataOnlyParents)
	{
		if (!Pair.Value)
			continue;
 
		UClass* KeyClass = Pair.Key.LoadSynchronous(); 
		if (!KeyClass)
			continue;
 
		if (CheckParentSuperclass(BP->ParentClass, KeyClass))
			return true;
	}
	return false;
}
 
void FMyAssetTypeActions_Blueprint::OpenAssetEditor(const TArray<UObject*>& InObjects,
	TSharedPtr<IToolkitHost> EditWithinLevelEditor)
{
	bool bAnyForced = false;
	for (UObject* Obj : InObjects)
	{
		if (const UBlueprint* BP = Cast<UBlueprint>(Obj))
		{
			if (ShouldForceFullEditorFor(BP))
			{
				bAnyForced = true;
				break;
			}
		}
	}
 
	if (!bAnyForced)
	{
		FAssetTypeActions_Blueprint::OpenAssetEditor(InObjects, EditWithinLevelEditor);
		return;
	}
 
	FBlueprintEditorModule& KismetModule =
		FModuleManager::LoadModuleChecked<FBlueprintEditorModule>("Kismet");
 
	const EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid() ? EToolkitMode::WorldCentric : EToolkitMode::Standalone;
 
	for (UObject* Obj : InObjects)
	{
		if (UBlueprint* BP = Cast<UBlueprint>(Obj))
		{
			if (ShouldForceFullEditorFor(BP))
			{
				// Open Full Blueprint Editor
				KismetModule.CreateBlueprintEditor(Mode, EditWithinLevelEditor, BP, false);
			}
			else
			{
				TArray<UObject*> Single{ Obj };
				FAssetTypeActions_Blueprint::OpenAssetEditor(Single, EditWithinLevelEditor);
			}
		}
		else
		{
			TArray<UObject*> Single{ Obj };
			FAssetTypeActions_Blueprint::OpenAssetEditor(Single, EditWithinLevelEditor);
		}
	}
}

After that, you only need to register the editor blueprint action. A good place to do it is in the StartupModule of the same editor module.

MyEditorModule.h

class FEM_SC_56Module : public IModuleInterface
{
    TSharedPtr<IAssetTypeActions> BlueprintActions;
 
public:
    virtual void StartupModule() override;
    virtual void ShutdownModule() override;
};

MyEditorModule.cpp

void FEM_SC_56Module::StartupModule()
{
	IAssetTools& AssetTools = FAssetToolsModule::GetModule().Get();
 
	BlueprintActions = MakeShared<FMyAssetTypeActions_Blueprint>();
	AssetTools.RegisterAssetTypeActions(BlueprintActions.ToSharedRef());
}
 
void FEM_SC_56Module::ShutdownModule()
{
	if (FModuleManager::Get().IsModuleLoaded("AssetTools") && BlueprintActions.IsValid())
	{
		IAssetTools& AssetTools = FAssetToolsModule::GetModule().Get();
		AssetTools.UnregisterAssetTypeActions(BlueprintActions.ToSharedRef());
	}
}

Unfortunately, I can’t tell you whether it’s included or not, but so far I haven’t seen anything similar in the development branch. I hope this code can help you and thus avoid having to modify the engine.

Regards,

Joan

Hi [mention removed]​,

My previous solution was intended as a workaround to avoid modifying the engine and to prevent potential conflicts for studios when updating their engine version. I’ll make sure the request is recieved by Epic, but whether it gets included natively or not will depend on them. The review process can take some time, so I can’t guarantee that it will be included. As mentioned, I’ll update the thread in the future if I recieve any new information.

Best Regards,

Joan

Thanks Maxim, I attached it to the report and let know Epic about it :slightly_smiling_face:

Best,

Joan