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);