UE5はBPオブジェクト丸ごとセーブすることはできないのでしょうか?
変数をSaveGameに一個一個保存してっていうのは何度もやってるんですが、例えば同じBP内で何種類か変数があって、さらにBPも何種類もあると全部変数をセーブするのは少しめんどうですよね。
SaveGame内の変数型で指定のBPのオブジェクト参照で変数を作ってみても上手くセーブされませんでした。
UE5はBPオブジェクト丸ごとセーブすることはできないのでしょうか?
変数をSaveGameに一個一個保存してっていうのは何度もやってるんですが、例えば同じBP内で何種類か変数があって、さらにBPも何種類もあると全部変数をセーブするのは少しめんどうですよね。
SaveGame内の変数型で指定のBPのオブジェクト参照で変数を作ってみても上手くセーブされませんでした。
そうですね 基本的にはブループリントを丸ごとSaveGameに保存することは基本的にはできません
ただし、BP は UObjectというものを継承しているので、 Serialize 関数を通してバイナリ化できます
目的によっては、これで事足りるかもしれません
バイナリにすれば、非 Truncate のプロパティ(=通常の変数など)は保存可能です 他のUObjectやアクターなどの直接の参照はサポートされていません
コード例↓
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Serialization/BufferArchive.h"
#include "Serialization/MemoryReader.h"
#include "Misc/FileHelper.h"
#include "HAL/PlatformFilemanager.h"
#include "MySerializableObject.generated.h"
/**
* UObjectをファイルに保存/読み込みできる汎用シリアライズクラス
*/
UCLASS(BlueprintType)
class UMySerializableObject : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, SaveGame)
int32 Health;
UPROPERTY(EditAnywhere, BlueprintReadWrite, SaveGame)
FString Name;
UPROPERTY(EditAnywhere, BlueprintReadWrite, SaveGame)
FVector Location;
private:
// 内部保存用バイナリデータ
TArray<uint8> SaveData;
public:
// 全プロパティをシリアライズ
virtual void Serialize(FArchive& Ar) override
{
Super::Serialize(Ar); // ← ここで標準プロパティをシリアライズ
for (TFieldIterator<FProperty> It(GetClass()); It; ++It)
{
FProperty* Property = *It;
if (Property && Property->HasAnyPropertyFlags(CPF_SaveGame))
{
void* ValuePtr = Property->ContainerPtrToValuePtr<void>(this);
Property->SerializeItem(Ar, ValuePtr); // ← ここで独自プロパティをシリアライズ
}
}
}
// バイナリとしてメモリに保存
void SaveToBinary()
{
SaveData.Reset();
FBufferArchive Archive;
Serialize(Archive);
SaveData = Archive;
}
// メモリから復元
void LoadFromBinary()
{
if (SaveData.Num() == 0) return;
FMemoryReader Reader(SaveData, true);
Serialize(Reader);
}
// ファイルに保存
bool SaveToFile(const FString& FilePath)
{
SaveToBinary();
if (SaveData.Num() == 0) return false;
return FFileHelper::SaveArrayToFile(SaveData, *FilePath);
}
// ファイルから読み込み
bool LoadFromFile(const FString& FilePath)
{
if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*FilePath))
{
return false;
}
if (FFileHelper::LoadFileToArray(SaveData, *FilePath))
{
LoadFromBinary();
return true;
}
return false;
}
};
使用例↓
// 保存
UMySerializableObject* Obj = NewObject<UMySerializableObject>();
Obj->Health = 150;
Obj->Name = TEXT("Test");
Obj->Location = FVector(10, 20, 30);
Obj->SaveToFile(FPaths::ProjectSavedDir() / TEXT("MyObjSave.bin"));
// 読み込み
UMySerializableObject* LoadedObj = NewObject<UMySerializableObject>();
LoadedObj->LoadFromFile(FPaths::ProjectSavedDir() / TEXT("MyObjSave.bin"));
UE_LOG(LogTemp, Log, TEXT("Loaded Health: %d, Name: %s"), LoadedObj->Health, *LoadedObj->Name);