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(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个参数FileName为Json/A.json,那么最终拼接得到的A.json绝对路径为:

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

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

UE4打包发布后,在Windows和Android平台上访问非Asset文件的更多相关文章

  1. VUE打包发布后无法访问js、css资源

    在vue开发中,本地测试以及测试环境中都没有遇到问题,当发布生产,有虚拟路径时,便出现js.css均报错404: 首先在config的index.js文件中,将assetsPublicPath修改为' ...

  2. Vue项目打包发布后CSS中的背景图片不显示

    相信有很多同学在学习vue的刚开始都遇到过项目打包发布后发现CSS中的背景图片不显示,具体如何解决只需要更改bind的配置即可 修改 build/utils.js 中的 generateLoaders ...

  3. 如果项目在IIS发布后,出现System.ComponentModel.Win32Exception: 拒绝访问。

    如果项目在IIS发布后,出现System.ComponentModel.Win32Exception: 拒绝访问. 那么就试试下面的办法. 步骤如下: 应用程序池=>设置应用程序池默认设置 将标 ...

  4. Qt在Android平台上实现html转PDF的功能

    Qt for Android Qt for Android enables you to run Qt 5 applications Android devices. All Qt modules ( ...

  5. 随笔之Android平台上的进程调度探讨

    http://blog.csdn.net/innost/article/details/6940136 随笔之Android平台上的进程调度探讨 一由来 最近在翻阅MediaProvider的时候,突 ...

  6. (转) Android平台上关于IM的实践总结

    前言 IM通信在互联网发展到现在已经是码农的世界里人尽皆知的技术,特别在当下移动互联网迅猛发展的时代这种技术的开发也更加火热,其中老牌的代表作就有QQ和MSN,和最近新崛起的微信,默默,易信,来往等眼 ...

  7. Android平台上最好的几款免费的代码编辑器

    使用正确的开发工具能够快速有效地完成源代码的编写和测试,使编程事半功倍.在网络信息高速发展的今天,移动设备的方便快捷已经深入人心,越来越多的程序员会选择在任何感觉舒适的地方使用移动设备查看或者编辑源代 ...

  8. unity3D开发的程序发布到Android平台上进行运行测试的详细步骤

    第一步    下载安装JDK 和SDK 1.需要配置java环境.点击链接进入ava的配置的方法:http://www.cnblogs.com/Study088/p/7496158.html 2.下载 ...

  9. [原]详解如何将cocos2dx项目编译到Android平台上的(方式一:Cywin+NDK)

    链接地址:http://m.blog.csdn.net/blog/yhc13429826359/29357815 2014-6-8阅读578 评论0 前言:cocos2dx作为一个开源的移动2D游戏框 ...

  10. OpenCV在Android平台上的应用

    今年8月份, OpenCV 2.3.1发布了. 虽然从2.2开始, OpenCV就号称支持Android平台, 但真正能让OpenCV在Android上运行起来还是在2.3.1版本上. 在这个版本上, ...

随机推荐

  1. python入门_模块2

    0.collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdic ...

  2. sql计算列中并非零值的平均值

    avg不考虑空值 AVG (NULLIF(Value, 0)) NULLIF(expression, expression) 如果两个 expression 相等,则返回 NULL,该 NULL 为第 ...

  3. 为什么需要学习ITSM/ITIL

    假如你需要管理一个超过20人的IT服务组织,一般会面临以下问题: 人多事杂活重,每个人都很累,工作却还是一团糟糕, 用户方怨声载道,领导也颇有微词,同事间也经常互相甩锅埋坑, 工作只是救火或者混日子, ...

  4. 11、操作系统安全加固-Windows 加固

    1.账号管理与认证授权 1.1.按用户类型分配账号 目的:根据系统要求,设定不同账户和组,管理员.数据库sa.审计用户.来宾用户等 实施方法: 打开本地用户和计算机管理器 或 打开运行,输入 lusr ...

  5. NumPy 数组创建方法与索引访问详解

    NumPy 创建数组 NumPy 中的核心数据结构是 ndarray,它代表多维数组.NumPy 提供了多种方法来创建 ndarray 对象,包括: 使用 array() 函数 array() 函数是 ...

  6. element-ui使用el-date-picker日期组件常见场景

    开始 最近一直在使用 element-ui中的日期组件. 所以想对日期组件常用的做一个简单的总结: 1.处理日期组件选择的时候面板联动问题 2.限制时间范围 解除两个日期面板之间的联动 我们发现2个日 ...

  7. Unity新的MeshData API学习

    在新版本的Unity中提供了MeshDataArray和MeshData等多个API,使Mesh数据操作支持多线程:以更好的支持DOTS. API文档:https://docs.unity3d.com ...

  8. 训练营 |【AIRIOT大学计划暑期训练营】第三期即将开营,报名从速!

    培养新生力量,聚焦产业融合.为了促进物联网产业的纵深发展和创新,推进教育链.产业链与创新链的有机衔接,提高学生理论.实践和创新能力,为行业培养更多优秀人才,航天科技控股集团股份有限公司将于2023年7 ...

  9. 部署springboot+vue项目文档(若依ruoyi项目部署步骤)

    摘自:https://blog.csdn.net/Dreamboy_w/article/details/104389797 部署springboot+vue项目文档(若依ruoyi项目部署步骤)一:部 ...

  10. 记一次U8的插件开发

    在u8上开发一个winform的插件用来实现不同账套之间的单据协同,使用的方法是用存储过程走数据库.因为原账套的数据量会很大,如果直接在插件上用单线程传输,那肯定会造成传输过程,u8卡死的.一种方法是 ...