engine crash when using delete_assets

I’m using this bit of hacky code to get the selected assets in the content browser:


@ue.uclass()
class MyEditorUtility(ue.GlobalEditorUtilityBase):
    pass
editor_util = MyEditorUtility()
editor_util.get_selected_assets()


First of all, there needs to be a simpler way to do something as common as getting selected assets in the content browser.

Second of all, working this way seems to cause instability when trying to delete assets in the same python script. When my scripts use unreal.EditorAssetLibrary.delete_asset(), they crash. If I remove the GlobalEditorUtilityBase bit, they don’t crash. If I use GlobalEditorUtilityBase and don’t delete assets, they don’t crash. The crash logs point to the MyEditorUtility hot-reloading at the time of crash. Has anyone else experienced this?

Oh wow!
I actually spent most of my day working on this! (Not the deleting part, but the way to get the selection. At the end, I decided to use c++ to do it.)

Bref, for your problem,
I got the same kind of issue long time ago with UObjects in general.
Deleting an asset (and some other actions) are breaking the current UObject, causing crash.

I tried your code, same thing happened.
I tried multiple ways to destroy the EditorUtility object before the delete call, but I was not able to stop the crash.

The only way I found is to do it with multiple command:

First, create the object (maybe during the startup?)



@ue.uclass()
class MyEditorUtility(ue.GlobalEditorUtilityBase):
    pass
editor_util = MyEditorUtility()


Then, delete the asset



path = editor_util.get_selected_assets()[0].get_path_name().split('.')[0]
unreal.EditorAssetLibrary.delete_asset(path)


But, this is really cheap, and may crash if the object become invalid between the instantiation and the usage.

Which brings me back to the solution I used to get the selection in c++.
(I will probably have a video for this on my youtube channel in a day or two)

If it is something you are open to do, here is my c++ code that you can call in python:

CppLib.h



#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "CppLib.generated.h"

UCLASS()
class UNREALPYTHONPROJECT_API UCppLib : public UBlueprintFunctionLibrary {
    GENERATED_BODY()
public:
    UFUNCTION(BlueprintCallable, Category = "Llama")
        static TArray<FString> GetSelectedAssets();
};


CppLib.cpp



#include "CppLib.h"
#include "Editor/ContentBrowser/Public/ContentBrowserModule.h" // PublicDependencyModuleNames -> "ContentBrowser"
#include "Editor/ContentBrowser/Private/SContentBrowser.h"       // PublicDependencyModuleNames -> "ContentBrowser"
#include "Runtime/AssetRegistry/Public/AssetRegistryModule.h"  // PublicDependencyModuleNames -> "AssetRegistry"

TArray<FString> UCppLib::GetSelectedAssets() {
    FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
    TArray<FAssetData> SelectedAssets;
    ContentBrowserModule.Get().GetSelectedAssets(SelectedAssets);
    TArray<FString> Result;
    for (FAssetData& AssetData : SelectedAssets) {
        Result.Add(AssetData.PackageName.ToString());
    }
    return Result;
}


Then, in Python:



import unreal
for path in unreal.CppLib.get_selected_assets():
    unreal.EditorAssetLibrary.delete_asset(path)


Let me know if it helped :slight_smile:

Hey Alex, thanks for your suggestion! I’ve been trying to avoid extending Unreal’s native python if possible, but I may have to for now. Thanks for sharing your C++ for doing this. I’ll give it a try soon and let you know.