게임 엔진/Unreal

[Unreal] [Example] 객체 직렬화 방법

2020. 6. 25. 23:02
목차
  1. Serialization (Memory Archive)
  2. Struct Serialization
  3. Object Serialization
  4. File Serialization

Serialization (Memory Archive)

언리얼에서 제공하는 기본적인 메모리 직렬화 객체 FMemoryArchive를 활용한 예제이다.

언리얼에서는 메모리 읽기, 쓰기 기능을 지원하기 위해 FMemoryArchive를 상속하여 FMemoryReader, FMemoryWriter 형태로 제공한다.

#include "Serialization/MemoryWriter.h"
#include "Serialization/MemoryReader.h"

void SerializationExamples::BaseExample()
{
	UE_LOG(LogTemp, Log, TEXT("BaseExample  Begin"));

	// write data to memory
	TArray<uint8> BufferArray;
	FMemoryWriter Writer(BufferArray);

	{
		uint32 A = 15;
		uint32 B = 75;
		FString C = TEXT("blabla");

		Writer << A;
		Writer << B;
		Writer << C;
		UE_LOG(LogTemp, Log, TEXT("BufferArray Num : %d"), BufferArray.Num());
	}

	// read data from memory
	FMemoryReader Reader(BufferArray);

	{
		uint32 A;
		uint32 B;
		FString C;

		Reader << A;
		Reader << B;
		Reader << C;

		UE_LOG(LogTemp, Log, TEXT("A : %u  B : %u  C : %s"), A, B, *C);
	}


	UE_LOG(LogTemp, Log, TEXT("BaseExample  End"));
}

 

Struct Serialization

구조체도 직렬화 로직을 정의해 준다면 같은 형태로 직렬화할 수 있다.

 

struct SerializationExampleData
{
	uint32 A;
	uint32 B;
	FString C;

	// for read / write serialization for this struct
	friend FArchive& operator<<(FArchive& Ar, SerializationExampleData& Data)
	{
		Ar << Data.A;
		Ar << Data.B;
		Ar << Data.C;
		return Ar;
	}
};

 

void SerializationExamples::StructExample()
{
	UE_LOG(LogTemp, Log, TEXT("StructSerializeExample  Begin"));

	TArray<uint8> BufferArray;
	FMemoryWriter Writer(BufferArray);

	{
		SerializationExampleData Data;
		Data.A = 99;
		Data.B = 13;
		Data.C = TEXT("blabla");

		Writer << Data;
		UE_LOG(LogTemp, Log, TEXT("BufferArray Num : %d"), BufferArray.Num());
	}


	FMemoryReader Reader(BufferArray);

	{
		SerializationExampleData Data;
		Reader << Data;
		UE_LOG(LogTemp, Log, TEXT("Data A : %u  Data B : %u  Data C : %s"), Data.A, Data.B, *Data.C);
	}


	{
		// need to seek to use again
		Reader.Seek(0);
		SerializationExampleData Data;
		Reader << Data;
		UE_LOG(LogTemp, Log, TEXT("Data A : %u  Data B : %u  Data C : %s"), Data.A, Data.B, *Data.C);
	}


	{
		// this will not work properly
		SerializationExampleData Data;
		Reader << Data;
		UE_LOG(LogTemp, Log, TEXT("Data A : %u  Data B : %u  Data C : %s  (Error Case)"), Data.A, Data.B, *Data.C);
	}

	{
		// once reader offset overflowed, it doesn't work properly even if seek offset
		Reader.Seek(0);
		SerializationExampleData Data;
		Reader << Data;
		UE_LOG(LogTemp, Log, TEXT("Data A : %u  Data B : %u  Data C : %s  (Error Case)"), Data.A, Data.B, *Data.C);
	}

	// safe example - just create archive object in brace
	{
		FMemoryReader MemReader(BufferArray);
		SerializationExampleData Data;
		MemReader << Data;
		UE_LOG(LogTemp, Log, TEXT("Data A : %u  Data B : %u  Data C : %s"), Data.A, Data.B, *Data.C);
	}

	UE_LOG(LogTemp, Log, TEXT("StructSerializeExample  End"));
}

 

Object Serialization

객체 직렬화 예제이다.

UENUM(BlueprintType)
enum class EType : uint8
{
	Type1,
	Type2
};

UCLASS()
class UNREALEXAMPLES_API USerializationExampleObject : public UObject
{
	GENERATED_BODY()

public:
	USerializationExampleObject() {}


	UPROPERTY(EditAnywhere, Category = "Voice Characteristics")
		EType Language;

	UPROPERTY(EditAnywhere, Category = "Conversion")
		FString SaveAssetTo;

	// 참조 형태의 변수는 Serialize 후 파일 Read/Write 과정에 문제가 생길 수 있다.
	// 따로 경로만 저장하는 형태로 개발하거나,
	// Config에 저장하는 형태로 개발하는것이 좋다.
	//UPROPERTY(EditAnywhere, Category = "Conversion")
	//	USkeleton* TargetSkeleton;

	UPROPERTY(EditAnywhere, Category = "Conversion")
		int32 ImportAudioNumber;

	UPROPERTY(EditAnywhere, Category = "Conversion")
		bool bInsertPlaySoundNotify;

	UPROPERTY(EditAnywhere, Category = "FilesToDump")
		bool bPhoneme;

	UPROPERTY(EditAnywhere, Category = "FilesToDump")
		bool bAnimClip;

	UPROPERTY(EditAnywhere, Category = "FilesToDump")
		bool bConversionLog;
};

 

void SerializationExamples::ObjectExample()
{
	UE_LOG(LogTemp, Log, TEXT("ObjectExample  Begin"));
	TArray<uint8> BufferArray;

	// write
	{
		FMemoryWriter Writer(BufferArray);

		USerializationExampleObject* Obj = NewObject<USerializationExampleObject>();
		Obj->Language = EType::Type2;
		Obj->SaveAssetTo = TEXT("Maybe/Some/Directory/Path/Here");
		Obj->ImportAudioNumber = 33;
		Obj->bInsertPlaySoundNotify = true;
		Obj->bPhoneme = false;
		Obj->bAnimClip = true;
		Obj->bConversionLog = false;

		Obj->Serialize(Writer);
		UE_LOG(LogTemp, Log, TEXT("BufferArray Num : %d"), BufferArray.Num());
	}

	// read
	{
		FMemoryReader Reader(BufferArray);
		USerializationExampleObject* Obj = NewObject<USerializationExampleObject>();

		Obj->Serialize(Reader);

		UE_LOG(LogTemp, Log, TEXT("Readed Data : %d  %s  %d  %d  %d  %d  %d"),
			Obj->Language,
			*Obj->SaveAssetTo,
			Obj->ImportAudioNumber,
			Obj->bInsertPlaySoundNotify,
			Obj->bPhoneme,
			Obj->bAnimClip,
			Obj->bConversionLog);
	}


	UE_LOG(LogTemp, Log, TEXT("ObjectExample  End"));
}

 

File Serialization

파일 직렬화 예제이다.

oid SerializationExamples::FileExample()
{
	UE_LOG(LogTemp, Log, TEXT("FileExample  Begin"));

	FString FullPath = FString::Printf(TEXT("%s%s"), *FPaths::ProjectSavedDir(), TEXT("save.txt"));

	// write
	FArchive* FileWriter = IFileManager::Get().CreateFileWriter(*FullPath);
	if (FileWriter)
	{
		FString T1 = FString(TEXT("AAA"));
		FString T2 = FString(TEXT("BBB"));
		*FileWriter << T1;
		*FileWriter << T2;
		FileWriter->Close();
		delete FileWriter;
		FileWriter = NULL;
	}

	// read (can be used with TSharedPtr, which deletes memory by-self)
	TSharedPtr<FArchive> FileReader = MakeShareable(IFileManager::Get().CreateFileReader(*FullPath));
	if (FileReader.IsValid())
	{
		FString Temp1;
		FString Temp2;

		*FileReader.Get() << Temp1;
		*FileReader.Get() << Temp2;

		FileReader->Close();
		UE_LOG(LogTemp, Log, TEXT("%s %s"), *Temp1, *Temp2);
	}

	UE_LOG(LogTemp, Log, TEXT("FileExample  End"));
}

 

메모리 데이터를 파일에 직렬화할 수도 있다.

void SerializationExamples::MemoryAndFileExample()
{
	UE_LOG(LogTemp, Log, TEXT("MemoryAndFileExample  Begin"));

	FString FullPath = FString::Printf(TEXT("%s%s"), *FPaths::ProjectSavedDir(), TEXT("save.txt"));

	// write (data -> memory -> file)
	TSharedPtr<FArchive> FileWriter = MakeShareable(IFileManager::Get().CreateFileWriter(*FullPath));
	if (FileWriter.IsValid())
	{
		TArray<uint8> Buffer;
		FMemoryWriter MemoryWriter(Buffer);

		SerializationExampleData Data;
		Data.A = 99;
		Data.B = 13;
		Data.C = TEXT("blabla");

		MemoryWriter << Data;

		*FileWriter << Buffer;
		FileWriter->Close();
	}


	// read (file -> memory -> data)
	TSharedPtr<FArchive> FileReader = MakeShareable(IFileManager::Get().CreateFileReader(*FullPath));
	if (FileReader.IsValid())
	{
		TArray<uint8> Buffer;
		*FileReader << Buffer;

		FMemoryReader MemoryReader(Buffer);

		SerializationExampleData Data;
		MemoryReader << Data;
		FileReader->Close();


		UE_LOG(LogTemp, Log, TEXT("Data A : %u  Data B : %u  Data C : %s"), Data.A, Data.B, *Data.C);
	}

	UE_LOG(LogTemp, Log, TEXT("MemoryAndFileExample  End"));
}

 

Github

https://github.com/insooneelife/UnrealExamples/blob/master/Source/UnrealExamples/Public/Serialization/SerializationExamples.h

'게임 엔진 > Unreal' 카테고리의 다른 글

[Unreal] [Editor] Slate를 이용한 커스텀 에디터 List View 제작  (0) 2020.06.29
[Unreal] [Editor] 프로퍼티 에디터 제작 방법  (0) 2020.06.26
[Unreal] [Editor] Slate를 이용한 에셋 경로 설정 다이얼로그 제작  (0) 2020.06.24
[Unreal] [Editor] [Example] Slate 예제 1  (0) 2020.06.22
[Unreal] [Editor] [Example] Slate 예제 2  (0) 2020.06.22
  1. Serialization (Memory Archive)
  2. Struct Serialization
  3. Object Serialization
  4. File Serialization
'게임 엔진/Unreal' 카테고리의 다른 글
  • [Unreal] [Editor] Slate를 이용한 커스텀 에디터 List View 제작
  • [Unreal] [Editor] 프로퍼티 에디터 제작 방법
  • [Unreal] [Editor] Slate를 이용한 에셋 경로 설정 다이얼로그 제작
  • [Unreal] [Editor] [Example] Slate 예제 1
AlgorFati
AlgorFati
algorfati@gmail.com
AlgorFati의 개발 기록algorfati@gmail.com
AlgorFati
AlgorFati의 개발 기록
AlgorFati
전체
오늘
어제
  • 분류 전체보기 (111)
    • 경제 (0)
    • 서비스 운영 (3)
    • 시행착오 (1)
    • 프로그래밍 (50)
      • CS 개념 (3)
      • 알고리즘 (32)
      • C++ (7)
      • C# (3)
      • OS (1)
      • Python (4)
    • 사업 (0)
    • Back End (1)
    • 생활 (1)
    • 정보 보안 (0)
    • 게임 개발 (1)
    • Tool (2)
    • 기술 (0)
    • AI (2)
    • 게임 엔진 (50)
      • Unreal (36)
      • Unity (14)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • asset to editor
  • TickGroup
  • 카카오
  • Unreal
  • pathfinding
  • Collision
  • aggregate geom
  • geom
  • unity
  • Event Handling
  • customize
  • Serialize
  • Editor
  • navmesh
  • Animation
  • Nullable
  • 취업
  • 대기업
  • debug draw
  • 알고리즘
  • c#
  • data asset
  • Slate
  • 비동기 프로그래밍
  • 프로그래머스
  • ml agent
  • hp bar
  • 코딩테스트
  • property editor
  • 불변성

최근 댓글

최근 글

hELLO · Designed By 정상우.
AlgorFati
[Unreal] [Example] 객체 직렬화 방법
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.