C++から変更アセットを保存する方法
使用バージョン:UE4.24.2
はじめに
エディタ上でアセットに対して何かしらの編集処理を行った際に自動で保存を実行したい場合があります。
そういった場合に対象アセットを保存するためのラッパー関数を用意する機会がありましたので、その備忘録となります。
準備
エディタ用のコードとなるため、エディタ用モジュールを用意しそちらへ実装します。
実装方法
依存モジュール
以下のモジュールを依存関係として追加する必要があります。
UnrealEd
ヘッダー
もし、BPから呼び出したい場合はUFUNCTION
でBPへ公開するよう設定すれば動作するかと思います。
#pragma once #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "AssetUtilityFunctionLibrary.generated.h" UCLASS() class XXX_API UAssetUtilityFunctionLibrary: public UBlueprintFunctionLibrary { GENERATED_BODY() public: /** * アセットの保存を実行します * * @param [in] InTargets 対象アセット * @param [in] bCheckDirty trueの場合は変更(Dirty)アセットのみが保存されます * @param [in] bPromptToSave trueの場合はアセットの保存確認を求められます。falseの場合は全て保存されます。 */ static void ExecuteSaveAssets(const TArray<UObject*>& InTargets, bool bCheckDirty = true, bool bPromptToSave = false); };
実装
#include "AssetUtilityFunctionLibrary.h" #if WITH_EDITOR #include "FileHelpers.h" #endif // WITH_EDITOR void UAssetUtilityFunctionLibrary::ExecuteSaveAssets(const TArray<UObject*>& InTargets, const bool bCheckDirty, const bool bPromptToSave) { TArray<UPackage*> PackagesToSave; for (UObject* Obj : InTargets) { if (IsValid(Obj)) { if (Obj->HasAnyFlags(RF_Transient)) { continue; } UPackage* Package = Obj->GetOutermost(); if (IsValid(Package)) { PackagesToSave.Add(Package); } } } if (0 < PackagesToSave.Num()) { FEditorFileUtils::PromptForCheckoutAndSave( PackagesToSave, bCheckDirty, bPromptToSave); } } //---
最後に
直接FEditorFileUtils::PromptForCheckoutAndSave()
を呼び出しても構わないのですが、個人的にUObject
で渡す方が使い勝手がいいと思ったので、簡単なラッパー関数を用意して使用しています。
MarkPackageDirty()
の呼び出しだけだと保存まではされないため、保存したい場合はこのような処理を行う必要があります。
専用アセットを用意したり、アセットの変更を検知して別のアセットの変更を行ったりする場合に利用する機会があるかもしれません。