인프런 커뮤니티 질문&답변

hush park님의 프로필 이미지
hush park

작성한 질문수

이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해

14강 언리얼 오브젝트 관리 II - 패키지

15:22에서 TopStudent 가 보이지 않는 문제가 있습니다.

작성

·

31

·

수정됨

0

출력로그까지 정상적으로 뜨는데, contents 폴더에서 TopStudent가 보이지 않습니다. TopStudent 가 나타나지 않는 이유가 궁금합니다.

일단 코드를 강의코드와 비교하며 개인적으로 재검토를 하였는데, 제가 다시 놓친 무언가가 있는 것인지, 아니며ㅑㄴ 현재 버전에서는 보이지 않게 된 것인지 궁금합니다.

DebugGame Editor로 실행하였으며, 출력로그 및 코드 내용은 다음과 같습니다.

(출력로그)

LogTemp: 저장할 파일 폴더 : ../../../../../../Users/qkrwo/Documents/Unreal Projects/UnrealSerialization/Saved

LogTemp: 저장할 파일 전체 경로 : ../../../../../../Users/qkrwo/Documents/Unreal Projects/UnrealSerialization/Saved/RawData.bin

LogTemp: 변경할 파일 전체 경로 : C:/Users/qkrwo/Documents/Unreal Projects/UnrealSerialization/Saved/RawData.bin

LogTemp: [RawData] 이름 이득우 순번 16

LogTemp: [ObjectData] 이름 이득우 순번 59

LogTemp: [JsonData] 이름 이득우 순번 59

LogTemp: 패키지가 성공적으로 저장되었습니다.

 


(Student.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

#include "UObject/NoExportTypes.h"

#include "Student.generated.h"

/**

*

*/

UCLASS()

class UNREALSERIALIZATION_API UStudent : public UObject

{

GENERATED_BODY()

public:

UStudent();

int32 GetOrder() const { return Order; }

void SetOrder(int32 InOrder) { Order = InOrder; }

const FString& GetName() const { return Name; }

void SetName(const FString& InName) { Name = InName; }

virtual void Serialize(FArchive& Ar) override;

private:

UPROPERTY()

int32 Order;

UPROPERTY()

FString Name;

};


(Student.cpp)

// Fill out your copyright notice in the Description page of Project Settings.

#include "Student.h"

UStudent::UStudent()

{

Order = -1;

Name = TEXT("홍길동");

}

void UStudent::Serialize(FArchive& Ar)

{

Super::Serialize(Ar);

 

Ar << Name;

Ar << Order;

}


(MyGameInstance.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

#include "Engine/GameInstance.h"

#include "MyGameInstance.generated.h"

struct FStudentData

{

FStudentData() {}

FStudentData(int32 InOrder, const FString& InName) : Order(InOrder), Name(InName) {}

 

friend FArchive& operator<<(FArchive& Ar, FStudentData& InStudentData)

{

Ar << InStudentData.Order;

Ar << InStudentData.Name;

return Ar;

}

int32 Order = -1;

FString Name = TEXT("홍길동");

};

/**

*

*/

UCLASS()

class UNREALSERIALIZATION_API UMyGameInstance : public UGameInstance

{

GENERATED_BODY()

public:

UMyGameInstance();

virtual void Init() override;

void SaveStudentPackage() const;

private:

static const FString PackageName;

static const FString AssetName;

UPROPERTY()

TObjectPtr<class UStudent> StudentSrc;

};


(MyGameInstance.cpp)

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyGameInstance.h"

#include "Student.h"

#include "JsonObjectConverter.h"

#include "UObject/SavePackage.h"

const FString UMyGameInstance::PackageName = TEXT("/Game/Student");

const FString UMyGameInstance::AssetName = TEXT("TopStudent");

void PrintStudentInfo(const UStudent* InStudent, const FString& InTag)

{

UE_LOG(LogTemp, Log, TEXT("[%s] 이름 %s 순번 %d"), InTag, InStudent->GetName(), InStudent->GetOrder());

}

UMyGameInstance::UMyGameInstance()

{

}

void UMyGameInstance::Init()

{

Super::Init();

FStudentData RawDataSrc(16, TEXT("이득우"));

const FString SavedDir = FPaths::Combine(FPlatformMisc::ProjectDir(), TEXT("Saved"));

UE_LOG(LogTemp, Log, TEXT("저장할 파일 폴더 : %s"), *SavedDir);

{

const FString RawDataFileName(TEXT("RawData.bin"));

FString RawDataAbsolutePath = FPaths::Combine(*SavedDir, *RawDataFileName);

UE_LOG(LogTemp, Log, TEXT("저장할 파일 전체 경로 : %s"), *RawDataAbsolutePath);

FPaths::MakeStandardFilename(RawDataAbsolutePath);

UE_LOG(LogTemp, Log, TEXT("변경할 파일 전체 경로 : %s"), *RawDataAbsolutePath);

FArchive* RawFileWriterAr = IFileManager::Get().CreateFileWriter(*RawDataAbsolutePath);

if (nullptr != RawFileWriterAr)

{

*RawFileWriterAr << RawDataSrc;

RawFileWriterAr->Close();

delete RawFileWriterAr;

RawFileWriterAr = nullptr;

 

}

FStudentData RawDataDest;

FArchive* RawFileReaderAr = IFileManager::Get().CreateFileReader(*RawDataAbsolutePath);

if (nullptr != RawFileReaderAr)

{

*RawFileReaderAr << RawDataDest;

RawFileReaderAr->Close();

delete RawFileReaderAr;

RawFileReaderAr = nullptr;

UE_LOG(LogTemp, Log, TEXT("[RawData] 이름 %s 순번 %d"), *RawDataDest.Name, RawDataDest.Order);

}

}

StudentSrc = NewObject<UStudent>();

StudentSrc->SetName(TEXT("이득우"));

StudentSrc->SetOrder(59);

{

const FString ObjectDataFileName(TEXT("ObjectData.bin"));

FString ObjectDataAbsolutePath = FPaths::Combine(*SavedDir, *ObjectDataFileName);

FPaths::MakeStandardFilename(ObjectDataAbsolutePath);

TArray<uint8> BufferArray;

FMemoryWriter MemoryWriterAr(BufferArray);

StudentSrc->Serialize(MemoryWriterAr);

if (TUniquePtr<FArchive> FileWriterAr = TUniquePtr<FArchive>(IFileManager::Get().CreateFileWriter(*ObjectDataAbsolutePath)))

{

*FileWriterAr << BufferArray;

FileWriterAr->Close();

}

TArray<uint8> BufferArrayFromFile;

if (TUniquePtr<FArchive> FileReaderAr = TUniquePtr<FArchive>(IFileManager::Get().CreateFileReader(*ObjectDataAbsolutePath)))

{

*FileReaderAr << BufferArrayFromFile;

FileReaderAr->Close();

}

FMemoryReader MemoryReaderAr(BufferArrayFromFile);

UStudent* StudentDest = NewObject<UStudent>();

StudentDest->Serialize(MemoryReaderAr);

PrintStudentInfo(StudentDest, TEXT("ObjectData"));

}

{

const FString JsonDataFileName(TEXT("StudentJsonData.txt"));

FString JsonDataAbsolutePath = FPaths::Combine(*SavedDir, *JsonDataFileName);

FPaths::MakeStandardFilename(JsonDataAbsolutePath);

TSharedRef<FJsonObject> JsonObjectSrc = MakeShared<FJsonObject>();

FJsonObjectConverter::UStructToJsonObject(StudentSrc->GetClass(), StudentSrc, JsonObjectSrc);

FString JsonOutString;

TSharedRef<TJsonWriter<TCHAR>> JsonWriterAr = TJsonWriterFactory<TCHAR>::Create(&JsonOutString);

if (FJsonSerializer::Serialize(JsonObjectSrc, JsonWriterAr))

{

FFileHelper::SaveStringToFile(JsonOutString, *JsonDataAbsolutePath);

}

FString JsonInString;

FFileHelper::LoadFileToString(JsonInString, *JsonDataAbsolutePath);

TSharedRef<TJsonReader<TCHAR>> JsonReaderAr = TJsonReaderFactory<TCHAR>::Create(JsonInString);

 

TSharedPtr<FJsonObject> JsonObjectDest;

if (FJsonSerializer::Deserialize(JsonReaderAr, JsonObjectDest))

{

UStudent* JsonStudentDest = NewObject<UStudent>();

if (FJsonObjectConverter::JsonObjectToUStruct(JsonObjectDest.ToSharedRef(), JsonStudentDest->GetClass(), JsonStudentDest))

{

PrintStudentInfo(JsonStudentDest, TEXT("JsonData"));

}

}

}

 

SaveStudentPackage();

}

void UMyGameInstance::SaveStudentPackage() const

{

UPackage* StudentPackage = CreatePackage(*PackageName);

EObjectFlags ObjectFlag = RF_Public | RF_Standalone;

UStudent* TopStudent = NewObject<UStudent>(StudentPackage, UStudent::StaticClass(), *AssetName, ObjectFlag);

TopStudent->SetName(TEXT("이득우"));

TopStudent->SetOrder(36);

const int32 NumofSubs = 10;

for (int32 ix = 1; ix <= NumofSubs; ++ix)

{

FString SubObjectName = FString::Printf(TEXT("Student%d"), ix);

UStudent* SubStudent = NewObject<UStudent>(TopStudent, UStudent::StaticClass(), *SubObjectName, ObjectFlag);

SubStudent->SetName(FString::Printf(TEXT("학생%d"), ix));

SubStudent->SetOrder(ix);

}

const FString PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension());

//UE_LOG(LogTemp, Log, TEXT("PakageFileName : %s"), *PackageFileName);

FSavePackageArgs SaveArgs;

SaveArgs.TopLevelFlags = ObjectFlag;

 

if (UPackage::SavePackage(StudentPackage, nullptr, *PackageFileName, SaveArgs))

{

UE_LOG(LogTemp, Log, TEXT("패키지가 성공적으로 저장되었습니다."));

}

}


UnrealSerialization.Build.cs 에서

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "Json", "JsonUtilities" });

를 정상적으로 삽입하였습니다.

 

 

답변 2

1

이득우님의 프로필 이미지
이득우
지식공유자

5.4 버전에서 안 보이는 문제가 있는데요. 우선은 학습은 그대로 진행해 주시고 조만간 해결책을 찾아서 공유드리겠습니다.

hush park님의 프로필 이미지
hush park
질문자

네 알겠습니다 답변 감사합니다 !!

이득우님의 프로필 이미지
이득우
지식공유자

관련해서 테스트를 해봤는데, 5.4부터는 애셋 생성이 Factory 클래스를 통해서만 가능하도록 변경된 것 같습니다.
Student클래스를 위한 전용 Factory를 만드는 방법이 꽤나 복잡해서 당분간은 콘텐츠 브라우저에서 안보이더라도 개념을 학습하는 형태로만 진행할 수 밖에 없을 것 같습니다.

hush park님의 프로필 이미지
hush park
질문자

네 알겠습니다 !!

0

안녕하세요, 인프런 AI 인턴입니다. hush park님.

TopStudent 에셋이 Content Browser에서 보이지 않는 문제에 대해 도움을 드리겠습니다.

문제의 원인과 해결 방안:

  1. 패키지와 에셋 이름 일치: 언리얼 엔진 5.3 버전에서는 패키지 이름과 에셋 이름이 일치해야 하는 경우가 있습니다. 현재 코드에서 PackageName"/Game/Student"이고, AssetName"TopStudent"로 설정되어 있습니다. 이 두 이름을 일치시켜 확인해 보세요.

  2. 에디터 재시작: 패키지를 저장한 후 에디터를 재시작하여 Content Browser를 새로고침하는 것이 문제 해결에 도움이 될 수 있습니다.

  3. 로그에서 확인: 저장 관련 로그를 통해 저장 과정에서 문제가 발생했는지 확인해 보세요. 특별히 오류가 없는지 로그를 세밀히 체크해 보는 것이 중요합니다.

  4. 콘텐츠 브라우저 설정: 콘텐츠 브라우저에서 보이지 않는 에셋은 필터링 설정으로 인해 가려져 있을 수 있으니, 콘텐츠 브라우저의 필터 옵션도 확인해 주세요.

  5. 파일 시스템 확인: 파일 탐색기에서 Student.uasset 파일을 확인하고, 에디터로 다시 한 번 임포트 시도해 보세요.

아래에 비슷한 문제에 대해 답변된 질문 링크를 첨부해 드립니다. 도움이 되실 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

hush park님의 프로필 이미지
hush park

작성한 질문수

질문하기