언리얼C++ 기초, 알고리즘 1문제
const FString SavedDirectoryPath = FPaths::Combine(FPlatformMisc::ProjectDir(), TEXT("Saved"));
UE_LOG(LogTemp, Log, TEXT("SavedDirectoryPath: %s"), *SavedDirectoryPath);
UE_LOG는 내부적으로 C언어의 printf와 같은 방식을 사용한다. 이 방식은 문자열을 출력할 때 문자열 데이터가 시작되는 시작 지점의 주소값(C 스타일 문자열)을 원한다.
FString = 언리얼이 똑똑하고 복잡한 객체 안에 길이 정보, 할당량 등등이 다 들어있음.
%s = FString객체를 이해하지 못한다 TCHAR&형태만 이해함
이떄 FString앞에 연산자를 붙이면, FString 객체가 가지고 있는 순수한 문자열 데이터의 시작 주소(`TCHAR`)를 반환하도록 설계되어있다.
객체들은 메모리상에서 서로의 주소를 참조하며 거미줄처럼 얽혀 있는 것을 오브젝트 그래프라고 한다.
FArchive는 데이터가 어디로 가는지(파일, 메모리, 네트워크) 상관하지 않는다. 오직 데이터를 어떻게 보낼 것인가에만 집중하는 추사 레이어이다.
C++의<< 연산자 오버로딩을 통해 저장과 로드 로직을 하나로 통합함. Archive.IsSaving() 혹은 Archive.IsLoading() 상태에 따라 <<의 동작이 내부적으로 결정된다. 그래서 저장용 함수와 로드용 함수를 따로 만들 필요 없이, 데이터의 순서만 정의하면 된다.
FPlatformMisc::ProjectDir()은 실행 중인 환경에 맞는 프로젝트 경로를 반환한다.
FPaths::Combine은 경로 조각들을 합칠 때 자동으로 슬래시 처리를 해줌으로써 경로 관련 버그를 원천 차단한다.
런타임에서 파일을 생성하거나 수정할 때는 상대 경로보다 확정된 절대 경로를 사용하는 것이 파일 유실 방지에 필수적이다.
상대경로 = .../Saved/MyFile.bin
절대경로 = C:/UnrealProjects/MyShooter/Saved/MyFile.bin
FArchive* WriterArchive = IFileManager::Get().CreateFileWriter(*AbsoluteFilePath);
if (WriterArchive != nullptr)
{
*WriterArchive << SerializedPigeon76Data;
WriterArchive->Close();
delete WriterArchive;
WriterArchive = nullptr;
}
IFileMananger::Get().CreateFileWriter가 반환하는 FArchive*는 언리얼의 가비지 컬렉션(GC) 대상이 아니다. 일반 C++ 객체임. 그래서 new처럼 heap데이터 관리 하듯이 관리를 해줘야한다. CreateFileWirter -> 쓰기만 기능, CreateFileReader -> 읽기만 가능
WriterArchive->Close(); : 하드디스크 버퍼에 남은 데이터를 완전히 쓰고 파일을 닫는다. 이 걸 해줘야 데이터가 저장된다.
delete WriterArchive; : 힙(Heap) 메모리에 할당된 아카이브 객체를 파괴
nullptr : 이미 해제된 메모리를 다시 가리키지 않도록(Dangling Pointer 방지) 주소값을 초기화
C++의 new 처럼 관리해줘야함