平时在内容浏览器中执行的资产操作,也可以通过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])