UE4打包发布后,在Windows和Android平台上访问非Asset文件
1、问题来源
最近的项目里面有个需求,要在打包之后的
exe
或者
apk
运行起来后访问工程
Content
或者安卓目录下的非
Asset
文件,比如
text
文件,
json
文件等,从中读取一些可随时修改的配置项信息。但是这些没法直接被
UE
平台序列化存储,因此需要做一点点额外的操作来实现我们的目标,假设工程目录
Content
里面有个
Json
目录,
Json
里面有个
A.json文件
,程序在运行时需要读取
A.json。
下面针对
Windows
和
Android
平台依次展开讨论怎么做。
2、Windows平台
第一步
,在
Project Settings->Project->Packaging下面,取消勾选Use Pak File,因为打包成.pak文件的话,Content目录下的所有资源(Asset文件或Non-Asset文件),都会被打包进一个.pak文件,后期无法随时修改。
第二步,在
Project Setting
顶部搜索
asset
,在
Additional Non-Asset Directories to Package右边点击加号,在新增的一行右侧点击"..."标记,新增一条路径指向Conent目录下的Json文件夹。
打包一下,文件夹里面显示我们的
Json/A
.json
已经作为独立文件成功打包到
WindowsNoEditor
目录下。
写几行测试一下看看行不行,假设我要蓝图里面读
A.json
,
C++
封装函数如下,其实主要是要通过
FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir()) + JsonName拼接得到A.json的正确绝对路径
:
1 bool UJsonOperator::FindValueWithGivenProperty(FString JsonName, FString FieldName, FString&Val)2 {3 FString AbsoluteJsonPath = FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir()) +JsonName;4 if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*AbsoluteJsonPath)) {5 UE_LOG(MiniFileReaderLog, Warning, TEXT("%s"), *AbsoluteJsonPath); //do not call UKismetSystemLibrary::PrintString in static function 6 7 FString JsonData;8 FFileHelper::LoadFileToString(JsonData, *AbsoluteJsonPath);9 10 /*convert fstring to json object.*/ 11 TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(JsonData);12 TSharedPtr<FJsonObject> RootJsonObj = MakeShareable(newFJsonObject);13 14 if(FJsonSerializer::Deserialize(JsonReader, RootJsonObj)) {15 UE_LOG(MiniFileReaderLog, Warning, TEXT("Json Data: %s"), *JsonData);16 17 TSharedPtr<FJsonValue> Member = RootJsonObj->TryGetField(FieldName);18 if(Member) {19 Val = Member->AsString();20 UE_LOG(MiniFileReaderLog, Log, TEXT("Property [%s], Value: %s"), *FieldName, *(Member->AsString()));21 }22 else{23 UE_LOG(MiniFileReaderLog, Warning, TEXT("Property [%s] specified not exists."), *FieldName);24 return false;25 }26 }27 else{28 UE_LOG(MiniFileReaderLog, Warning, TEXT("FJsonSerializer::Deserialize Failed!"));29 return false;30 }31 }32 else{33 UE_LOG(MiniFileReaderLog, Error, TEXT("File : %s not exists."), *JsonName);34 return false;35 }36 return true;37 }
3、Android平台
Android
平台略有不同,
UE
工程发布到安卓设备并启动之后,会在安卓设备的
/storage/emulated/0/UE4Game
目录下新建一个和
UE Project Name
的同名目录。该目录存放程序的运行数据,此处工程名假设为
FunctionProject
。
第一步,在运行数据目录新建
Json/A.json
,如下所示,里面存放程序需要读取的属性数据信息。
第二步,写一段示例代码读取到该目录下的A.json文件,如下所示:
bool UJsonOperator::LoadRawContentsToString(FString FileName, FString&FileContents)
{#if PLATFORM_ANDROID externFString GFilePathBase;
FString tmp= GFilePathBase + FString("/UE4Game/") + UKismetSystemLibrary::GetGameName() + FString("/") +FileName;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, FString::Printf(TEXT("%s"), *tmp));return FFileHelper::LoadFileToString(FileContents, *tmp);#else const FString ThePath =FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir());
UE_LOG(MiniFileReaderLog, Log, TEXT("Json Path: %s"), *(ThePath +FileName));return FFileHelper::LoadFileToString(FileContents, *(ThePath +FileName));#endif}
此处,
UKismetSystemLibrary::GetGameName()
就是获取
UE4Game
目录下的
APP
发布名称,可以理解为
Android APP
运行数据的根目录,函数传入参数的第
1
个参数
FileName
为
Json/A.json
,那么最终拼接得到的
A.json
绝对路径为:
/storage/emulated/0/UE4Game/FunctionProject/Json/A.json
拿到这个绝对路径,就可以读取文件内容了,到此结束!