//指定文件路径
FString PathToLoad = "Texture2D'/Game/timg.timg'";
//通过路径Load进来,并转换成Texture2D
UTexture2D* tmpTexture = Cast<UTexture2D>(StaticLoadObject(UTexture2D::StaticClass(), NULL, *(PathToLoad )));
//改变Texture2D的属性
tmpTexture->LODGroup = TextureGroup::TEXTUREGROUP_Pixels2D;
//得到保存的路径
FString FileName = tmpTexture->GetFName().ToString();
FString pathPackage = FString("/Game/") + FileName;
//根据路径创建Package
UPackage * Package = CreatePackage(nullptr, *pathPackage);
//设置改变并保存
Package->SetDirtyFlag(true);
UEditorLoadingAndSavingUtils::SaveDirtyPackages(false, true);
-----------------------------------------------------------
其他资料:
Rama的插件:
https://github.com/EverNewJoy/VictoryPlugin
将读取方法暴露给蓝图了,但是目前版本没有保存
-----------------------------------------------------------------------
动态创建package资源并且导出资源
void UTestShaderBlueprintLibrary::ExportTexture(UTexture2D* TextureToBeExpot)
{
//TextureToBeExpot->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
//TextureToBeExpot->SRGB = 0;
//TextureToBeExpot->UpdateResource();
//TextureToBeExpot->Source.BulkData
FTexture2DMipMap& mipmap = TextureToBeExpot->PlatformData->Mips[4];
void* Data = mipmap.BulkData.Lock(LOCK_READ_WRITE);
uint32* PixelPointer = (uint32*)Data;
if (PixelPointer == nullptr)
{
mipmap.BulkData.Unlock();
return;
}
int32 texturex = TextureToBeExpot->PlatformData->SizeX;
int32 texturey = TextureToBeExpot->PlatformData->SizeY;
TArray<uint8>colors;
colors.AddUninitialized(texturex * texturey * 4);
for (int32 x = 0; x < texturex * texturey; x++)
{
uint32 EncodedPixel = *PixelPointer;
//B
colors[4 * x] = (EncodedPixel & 0x000000FF);
//G
colors[4 * x + 1] = (EncodedPixel & 0x0000FF00) >> 8;
//R
colors[4 * x + 2] = (EncodedPixel & 0x00FF0000) >> 16;
//A
colors[4 * x + 3] = (EncodedPixel & 0xFF000000) >> 24;
PixelPointer++;
}
mipmap.BulkData.Unlock();
//----------------------------------------------------------//
// Texture Information
int width = texturex;
int height = texturey;
FString FileName = TextureToBeExpot->GetFName().ToString();
// Create Package
FString pathPackage = FString("/Game/MyTextures/") + FileName;
//FString absolutePathPackage = FPaths::ProjectContentDir() + "/MyTextures/";
//FPackageName::RegisterMountPoint(*pathPackage, *absolutePathPackage);
UPackage * Package = CreatePackage(nullptr, *pathPackage);
// Create the Texture
//FName TextureName = MakeUniqueObjectName(Package, UTexture2D::StaticClass(), FName(*FileName));
//FName TextureName = FPaths::GetBaseFilename(absolutePathPackage);
UObject* TexObj = NewObject<UTexture2D>(Package, TextureToBeExpot->GetFName(), RF_Public | RF_Standalone);
UTexture2D* Texture = Cast<UTexture2D>(TexObj);
Texture->Source.Init(width, height, /*NumSlices=*/ 1, /*NumMips=*/ 1, TSF_BGRA8, colors.GetData());
Texture->PlatformData = new FTexturePlatformData();
Texture->PlatformData->SizeX = width;
Texture->PlatformData->SizeY = height;
Texture->PlatformData->PixelFormat = PF_B8G8R8A8;
//Texture->Source.Format =
// Passing the pixels information to the texture
FTexture2DMipMap* Mip = new(Texture->PlatformData->Mips) FTexture2DMipMap();
Mip->SizeX = width;
Mip->SizeY = height;
Mip->BulkData.Lock(LOCK_READ_WRITE);
uint8* TextureData = (uint8 *)Mip->BulkData.Realloc(height * width * sizeof(uint8) * 4);
FMemory::Memcpy(TextureData, colors.GetData(), sizeof(uint8) * height * width * 4);
Mip->BulkData.Unlock();
// Updating Texture & mark it as unsaved
Texture->AddToRoot();
FAssetRegistryModule::AssetCreated(Texture);
Texture->UpdateResource();
Package->SetDirtyFlag(true);
//Texture->PostEditChange();
UE_LOG(LogTemp, Log, TEXT("Texture created: %s"), &FileName);
//---------------------------------------------------------//
//TextureToBeExpot->
//FEditorFileUtils::PromptForCheckoutAndSave(PackagesToSave, false, /*bPromptToSave=*/ false);
FAssetToolsModule& AssetToolModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
IAssetTools& AssetTool = AssetToolModule.Get();
TArray<UObject*>Textures;
Textures.Add(Texture);
AssetTool.ExportAssetsWithDialog(Textures, true);
}
注意package的路径,如果路径不对资源将创建失败。
------------------------------------------------------------------------------------------------------------------
老外的分享
https://answers.unrealengine.com/questions/500286/saveload-package.html
--------------------------------------------------------------------------------------------------------
[UE4]C++实现动态加载的问题:LoadClass<T>()和LoadObject<T>()
C++静态加载问题:ConstructorHelpers::FClassFinder()和FObjectFinder()
http://aigo.iteye.com/blog/2281373
C++实现动态加载UObject:StaticLoadObject();以Texture和Material为例
http://aigo.iteye.com/blog/2268056
动态加载UObject和动态加载UClass分别用LoadObject<T>(),和LoadClass<T>() ,两者均在在UObjectGlobals.h中。
区别:
LoadObject<T>()用来加载非蓝图资源,比如动画、贴图、音效等资源;
LoadClass<T>()用来加载蓝图并获取蓝图Class,比如角色蓝图。如果要用蓝图创建对象,必须先通过LoadClass获取class,然后再通过SpawnActor生成对象。
LoadClass参数注意事项:
另外注意:LoadClass<T>的模版名称,不能直接写UBlueprint,例如:LoadClass<UBlueprint>是错误的,创建蓝图时选择的是什么父类,则写对应的父类名,假如是Actor,那么要写成:LoadClass<AActor>,否则无法加载成功。
路径名也必须带_C后缀(LoadObject不需要带_C后缀),例如,蓝图路径是:Blueprint'/Game/Blueprints/MyBP.MyBP',
加后缀以后,则是:Blueprint'/Game/Blueprints/MyBP.MyBP_C',
例子:
Cpp代码
- UClass* Test = LoadClass<AActor>(NULL, TEXT("Blueprint'/Game/Blueprints/MapPathBrush_BP.MapPathBrush_BP_C'"));
官方还没出文档,只能先看代码注释:
Cpp代码
- // Load an object.
- template< class T >
- inline T* LoadObject( UObject* Outer, const TCHAR* Name, const TCHAR* Filename=nullptr, uint32 LoadFlags=LOAD_None, UPackageMap* Sandbox=nullptr )
- {
- return (T*)StaticLoadObject( T::StaticClass(), Outer, Name, Filename, LoadFlags, Sandbox );
- }
Cpp代码
- // Load a class object.
- template< class T >
- inline UClass* LoadClass( UObject* Outer, const TCHAR* Name, const TCHAR* Filename=nullptr, uint32 LoadFlags=LOAD_None, UPackageMap* Sandbox=nullptr )
- {
- return StaticLoadClass( T::StaticClass(), Outer, Name, Filename, LoadFlags, Sandbox );
- }
Cpp代码
- /**
- * Find or load an object by string name with optional outer and filename specifications.
- * These are optional because the InName can contain all of the necessary information.
- *
- * @param ObjectClass The class (or a superclass) of the object to be loaded.
- * @param InOuter An optional object to narrow where to find/load the object from
- * @param InName String name of the object. If it's not fully qualified, InOuter and/or Filename will be needed
- * @param Filename An optional file to load from (or find in the file's package object)
- * @param LoadFlags Flags controlling how to handle loading from disk
- * @param Sandbox A list of packages to restrict the search for the object
- * @param bAllowObjectReconciliation Whether to allow the object to be found via FindObject in the case of seek free loading
- *
- * @return The object that was loaded or found. NULL for a failure.
- */
- COREUOBJECT_API UObject* StaticLoadObject( UClass* Class, UObject* InOuter, const TCHAR* Name, const TCHAR* Filename = NULL, uint32 LoadFlags = LOAD_None, UPackageMap* Sandbox = NULL, bool bAllowObjectReconciliation = true );
- COREUOBJECT_API UClass* StaticLoadClass(UClass* BaseClass, UObject* InOuter, const TCHAR* Name, const TCHAR* Filename = NULL, uint32 LoadFlags = LOAD_None, UPackageMap* Sandbox = NULL);
LoadObject参数注意事项:
LoadObject加载例子,不需要添加后缀:
Cpp代码
- UTexture2D* Tex = LoadObject<UTexture2D>(NULL, TEXT("Texture2D'/Game/Textures/UI/tex_test001.tex_test001'"));
可以用LoadObject加载的文件包括:
Texture、Material、SoundWave、SoundCue、ParticlesSystem、AnimMontage、BlendSpace(1D,2D,3D)、AnimSequence、AnimBlueprint、SkeletalMesh等等。这些文件的父类都是UObject,所以也可以先加载为UObject*然后再强转为具体的类型,例如:
Cpp代码
- UObject* Obj = LoadObject<UObject>(NULL, TEXT("SkeletalMesh'/Game/MyMesh.MyMesh'"));
- USkeletalMesh* MyMesh = Cast<USkeletalMesh*>(Obj);
https://aigo.iteye.com/blog/2268056
https://aigo.iteye.com/blog/2281558
加载Material和Texture
Cpp代码
- struct FConstructorStatics
- {
- ConstructorHelpers::FObjectFinderOptional<UTexture> TextureFinder;
- ConstructorHelpers::FObjectFinderOptional<UMaterial> MaterialFinder;
- FConstructorStatics()
- : TextureFinder(TEXT("Texture2D'/Game/Textures/2DBackground.2DBackground'"))
- , MaterialFinder(TEXT("Material'/Game/Materials/DynamicTextureMaterial.DynamicTextureMaterial'"))
- {
- }
- };
- static FConstructorStatics ConstructorStatics;
- Texture = ConstructorStatics.TextureFinder.Get();
- UMaterial* Material = ConstructorStatics.MaterialFinder.Get();
- DynamicMaterial = UMaterialInstanceDynamic::Create(Material, this);
设置调用加载好的Material和Texture:
Cpp代码
- DynamicMaterial->SetTextureParameterValue(FName("DynamicTexture"), Texture);
- Mesh->SetMaterial(0, DynamicMaterial);
如果资源永不再使用,想销毁资源对象,代码如下:
Cpp代码
- Texture2D* mytex; //这里假设mytex合法有效
- mytex->ConditionalBeginDestroy();
- mytex = NULL;
- GetWorld()->ForceGarbageCollection(true);