UE4打包发布后,在Windows和Android平台上访问非Asset文件

ue4,windows,android,asset · 浏览次数 : 0

小编点评

**问题**: 如何在打包后的exe或apk中访问Content或安卓目录下的非Asset文件,如text文件、json文件等,并从中读取可随时修改的配置项信息? **解决方案**: ### Windows平台 1. **取消勾选Use Pak File**:在Project Settings->Project->Packaging中取消勾选Use Pak File,以便在打包过程中包含非Asset文件。 2. **添加非资产目录**:在Project Setting的顶部搜索`asset`,在`Additional Non-Asset Directories to Package`右侧点击加号,然后通过`...`标记添加Content目录下的Json文件夹路径。 3. **打包并测试**:打包项目并检查Json/A.json文件是否已作为独立文件成功打包到WindowsNoEditor目录下。编写测试代码以在蓝图中读取A.json文件。 ### Android平台 1. **创建运行数据目录**:在Android设备的`/storage/emulated/0/UE4Game`目录下创建与UE Project Name同名的目录,用于存放程序的运行数据。 2. **写入配置文件**:在创建的运行数据目录中新建Json/A.json文件,并写入需要读取的属性数据信息。 3. **读取文件内容**:编写代码(如UJsonOperator::LoadRawContentsToString函数)以从该目录下的A.json文件中读取文件内容。 **总结**: 通过上述步骤,我们可以在Windows平台和Android平台上实现在打包后的exe或apk中访问Content或安卓目录下的非Asset文件,并从中读取可随时修改的配置项信息。

正文

 

1、问题来源

  最近的项目里面有个需求,要在打包之后的exe或者apk运行起来后访问工程Content或者安卓目录下的非Asset文件,比如text文件,json文件等,从中读取一些可随时修改的配置项信息。但是这些没法直接被UE平台序列化存储,因此需要做一点点额外的操作来实现我们的目标,假设工程目录Content里面有个Json目录,Json里面有个A.json文件,程序在运行时需要读取A.json。

  下面针对WindowsAndroid平台依次展开讨论怎么做。

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.jsonC++封装函数如下,其实主要是要通过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(new FJsonObject);
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
    extern FString 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个参数FileNameJson/A.json,那么最终拼接得到的A.json绝对路径为:

/storage/emulated/0/UE4Game/FunctionProject/Json/A.json

  拿到这个绝对路径,就可以读取文件内容了,到此结束!

与UE4打包发布后,在Windows和Android平台上访问非Asset文件相似的内容: