UE4编辑器Python编程3——内容浏览器操作

平时在内容浏览器中执行的资产操作,也可以通过Python脚本执行

保存资产和目录

# coding: utf-8

import unreal

def saveAsset():
    unreal.EditorAssetLibrary.save_asset(# 保存资源
        '/Game/Textures/TX_LightSpotMove', only_if_is_dirty=False)

def saveDirectory():
    unreal.EditorAssetLibrary.save_directory(# 保存目录
        '/Game', only_if_is_dirty=False, recursive=True)

def getPackageFromPath():
    return unreal.load_package('/Game/Textures/TX_LightSpotMove')# 从指定目录获取包

def getAllDirtyPackage():
    packages = unreal.Array(unreal.Package)
    for x in unreal.EditorLoadingAndSavingUtils.get_dirty_content_packages():
        packages.append(x)
    for x in unreal.EditorLoadingAndSavingUtils.get_dirty_map_packages():  # map和普通资产不一样
        packages.append(x)
    return packages

def saveAllDirtyPackages(show_dialog=False):
    if show_dialog:
        unreal.EditorLoadingAndSavingUtils.save_dirty_packages_with_dialog(
            save_map_packages=True, save_content_packages=True)
    else:
        unreal.EditorLoadingAndSavingUtils.save_dirty_packages(
            save_map_packages=True, save_content_packages=True)

def savePackages(packages=[], show_dialog=False):
    if show_dialog:
        unreal.EditorLoadingAndSavingUtils.save_packages_with_dialog(# 保存指定包
            packages, only_dirty=False)
    else:
        unreal.EditorLoadingAndSavingUtils.save_packages(
            packages, only_dirty=False)

创建、复制、重命名、删除

对于文件夹:

# coding: utf-8

import unreal

def createDirectory():
    unreal.EditorAssetLibrary.make_directory('/Game/MyNewDirectory')

def duplicateDirectory():
    return unreal.EditorAssetLibrary.duplicate_directory(
        '/Game/MyNewDirectory', '/Game/MyNewDirectory_Duplicated')

def deleteDirectory():
    unreal.EditorAssetLibrary.delete_directory('/Game/MyNewDirectory')

def directoryExist():
    print(unreal.EditorAssetLibrary.does_directory_exist('/Game/MyNewDirectory'))
    print(unreal.EditorAssetLibrary.does_directory_exist(
        '/Game/MyNewDirectory_Duplicated'))

def renameDirectory():
    unreal.EditorAssetLibrary.rename_directory(
        '/Game/MyNewDirectory_Duplicated', '/Game/MyNewDirectory_Renamed')

对于单个资产:

# coding: utf-8

import unreal

def duplicateAsset():
    return unreal.EditorAssetLibrary.duplicate_asset(
        '/Game/StaticMesh/c', '/Game/StaticMesh/c_Duplicate')

def deleteAsset():
    unreal.EditorAssetLibrary.delete_asset('/Game/StaticMesh/c_Duplicate')

def assetExist():
    print(unreal.EditorAssetLibrary.does_asset_exist('/Game/StaticMesh/c'))
    print(unreal.EditorAssetLibrary.does_asset_exist(
        '/Game/StaticMesh/c_Duplicate'))

def renameAsset():
    unreal.EditorAssetLibrary.rename_asset(
        '/Game/StaticMesh/c', '/Game/StaticMesh/c_Renamed')

def duplicateAssetDialog(show_diaglog=True):
    if show_diaglog:
        unreal.AssetToolsHelpers.get_asset_tools().duplicate_asset_with_dialog(
            'c_Duplicate',                               # asset_name
            '/Game/StaticMesh',                         # package_path
            unreal.load_asset('/Game/StaticMesh/c'))  # original_object
    else:
        unreal.AssetToolsHelpers.get_asset_tools().duplicate_asset(
            'c_Duplicate',
            '/Game/StaticMesh',
            unreal.load_asset('/Game/StaticMesh/c'))

def renameAssetDialog(show_diaglog=True):
    first_rename_data = unreal.AssetRenameData(unreal.load_asset(
        '/Game/StaticMesh/c'), '/Game/StaticMesh', 'c_Renamed')
    second_rename_data = unreal.AssetRenameData(unreal.load_asset(
        '/Game/StaticMesh/c_Duplicate'), '/Game/StaticMesh', 'c_Duplicate_Renamed')

    if show_diaglog:
        unreal.AssetToolsHelpers.get_asset_tools().rename_assets_with_dialog(
            [first_rename_data, second_rename_data])
    else:
        unreal.AssetToolsHelpers.get_asset_tools().rename_assets(
            [first_rename_data, second_rename_data])

修改文件夹的颜色

修改文件夹的颜色是通过修改配置文件完成的,先使用C++修改配置文件:

UFUNCTION(BlueprintCallable, Category = "Unreal Python")
static void SetFolderColor(FString folderPath, FLinearColor Color)
{
     
	GConfig->SetString(TEXT("PathColor"), *folderPath, *Color.ToString(), GEditorPerProjectIni);
}

在使用Python调用C++函数:

# coding: utf-8

import unreal

def getGradientColor(x):
    return (0, 1, 1, 1)

def generateColoredDirectories():
    for x in range(100, 400):
        dir_path = '/Game/PythonGenerated/'+str(x)
        linear_color = getGradientColor(x)
        unreal.ZFunctions.set_folder_color(dir_path, linear_color)
        unreal.EditorAssetLibrary.make_directory(dir_path)

打开特定资源的编辑器

目前Python中只有为特定资源打开编辑窗口的功能,关闭功能还要通过C++
C++:

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
// (模块的的C#脚本中还要添加"UnrealEd"模块的依赖)
#include "Editor/UnrealEd/Public/Toolkits/AssetEditorManager.h"
#include "ZFunctions.generated.h"

UCLASS()
class TEMP_SCRIPT_API UZFunctions : public UBlueprintFunctionLibrary
{
     
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable,Category="Unreal Python")
	static void CloseEditorForAssets(TArray<UObject*> Assets)
	{
     
		FAssetEditorManager& AssetEditorManager = FAssetEditorManager::Get();
		for (UObject* Asset : Assets)
		{
     
			AssetEditorManager.CloseAllEditorsForAsset(Asset);
		}
	}

	UFUNCTION(BlueprintCallable, Category = "Unreal Python")
	static TArray<UObject*> GetAssetsOpenedInEditor()
	{
     
		FAssetEditorManager& AssetEditorManager = FAssetEditorManager::Get();
		return AssetEditorManager.GetAllEditedAssets();
	}
};

Python:

# coding: utf-8

import unreal

# 先调用Python为指定文件打开编辑器
def openAssets():
    assets = [unreal.load_asset('/Game/Textures/Colours'),
              unreal.load_asset('/Game/SkeletalMeshes/Character'),
              unreal.load_asset('/Game/Sounds/kof')]
    unreal.AssetToolsHelpers.get_asset_tools().open_editor_for_assets(assets)

def getAllOpenedAssets():
    return unreal.ZFunctions.get_assets_opened_in_editor()

def closeAssets():
    assets = getAllOpenedAssets()# 获取打开的资源
    unreal.ZFunctions.close_editor_for_assets(assets)# 关闭

选中资产

选中资产也需要借助C++实现,然后使用Python调用C++,C++代码如下:

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Editor/ContentBrowser/Public/ContentBrowserModule.h"// "ContentBrowser"
#include "Editor/ContentBrowser/Private/SContentBrowser.h"// "ContentBrowser"
#include "Runtime/AssetRegistry/Public/AssetRegistryModule.h"// "AssetRegistry"
#include "ZFunctions.generated.h"

UCLASS()
class TEMP_SCRIPT_API UZFunctions : public UBlueprintFunctionLibrary
{
     
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "Unreal Python")
		static TArray<FString> GetSelectedAssets()
	{
     
		FContentBrowserModule& ContentBrowserModule = 
			FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");

		TArray<FAssetData> SelectedAssets;
		ContentBrowserModule.Get().GetSelectedAssets(SelectedAssets);

		TArray<FString> Result;
		for (auto& AssetData : SelectedAssets)
		{
     
			Result.Add(AssetData.PackageName.ToString());
		}
		return Result;
	}

	UFUNCTION(BlueprintCallable, Category = "Unreal Python")
		static void SetSelectedAssets(TArray<FString> Paths)
	{
     
		FContentBrowserModule& ContentBrowserModule =
			FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
		FAssetRegistryModule& AssetRegistryModule =
			FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");

		TArray<FName> PathsName;
		for (auto Path : Paths)
		{
     
			PathsName.Add(*Path);
		}

		FARFilter AssetFilter;
		AssetFilter.PackageNames = PathsName;

		TArray<FAssetData> AssetDatas;
		AssetRegistryModule.Get().GetAssets(AssetFilter, AssetDatas);
		ContentBrowserModule.Get().SyncBrowserToAssets(AssetDatas);
	}

	UFUNCTION(BlueprintCallable, Category = "Unreal Python")
		static TArray<FString> GetSelectedFolders()
	{
     
		FContentBrowserModule& ContentBrowserModule =
			FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");

		TArray<FString> SelectedFolders;
		ContentBrowserModule.Get().GetSelectedFolders(SelectedFolders);// 只有在右侧的那一栏选中采选选中!
		return SelectedFolders;
	}



	UFUNCTION(BlueprintCallable, Category = "Unreal Python")
		static void SetSelectedFolders(TArray<FString> Paths)
	{
     
		FContentBrowserModule& ContentBrowserModule =
			FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");

		TArray<FString> SelectedFolders;
		ContentBrowserModule.Get().SyncBrowserToFolders(Paths);
	}
};

Python:

# coding: utf-8

import unreal

def showAssetsInContentBrowers():
    ''' 选中指定的资产 '''
    paths = ['/Game/Textures/Colours', '/Game/SkeletalMeshes/Character']
    unreal.EditorAssetLibrary.sync_browser_to_objects(paths)  # 选中指定的资产

def getSelectedAssets():
    return unreal.ZFunctions.get_selected_assets()

def setSelectedAssets():
    ''' 通过C++实现的选中指定的资产 '''
    paths = ['/Game/Textures/Colours', '/Game/SkeletalMeshes/Character']
    return unreal.ZFunctions.set_selected_assets(paths)

def getSelectedFolders():
    return unreal.ZFunctions.get_selected_folders()

def setSelectedFolders():
    paths = ['/Game/Textures', '/Game/SkeletalMeshes']
    return unreal.ZFunctions.set_selected_folders(paths)

创建资产

# coding: utf-8

import unreal

def createGenericAsset(asset_path='', unique_name=True, asset_class=None, asset_factory=None):
    # 1、创建独一无二的包和资产名
    if unique_name:
        asset_path, asset_name = unreal.AssetToolsHelpers.get_asset_tools(
        ).create_unique_asset_name(
            base_package_name=asset_path,  # 包名
            suffix='')                     # 后缀
    # 2、创建资源
    if not unreal.EditorAssetLibrary.does_asset_exist(asset_path=asset_path):
        # 对包名进行分割,分割出路径和资产名
        path = asset_path.rsplit('/', 1)[0]
        name = asset_path.rsplit('/', 1)[1]
        return unreal.AssetToolsHelpers.get_asset_tools().create_asset(
            asset_name=name,
            package_path=path,
            asset_class=asset_class,
            factory=asset_factory
        )
    return unreal.load_asset(asset_path)

def createGenericAsset_EXAMPLE():
    base_path = '/Game/GenericAssets/'
    generic_assets = [
        [base_path+'sequence',   unreal.LevelSequence,  unreal.LevelSequenceFactoryNew()],
        [base_path+'material',   unreal.Material,       unreal.MaterialFactoryNew()],
        [base_path+'world',      unreal.World,           unreal.WorldFactory()],
        [base_path+'particle',   unreal.ParticleSystem, unreal.ParticleSystemFactoryNew()],
        [base_path+'flipbook',   unreal.PaperFlipbook,  unreal.PaperFlipbookFactory()],
        [base_path+'data_table', unreal.DataTable,      unreal.DataTableFactory()]# 这个无效
    ]
    for asset in generic_assets:
        print createGenericAsset(asset[0], True, asset[1], asset[2])

你可能感兴趣的:(#,编辑器Python编程)