虚幻引擎 支持将项目发布到 安卓(Android) 移动设备上,并且提供了若干功能帮你将项目发布到 谷歌游戏商店。本节包含了如何设置Android开发环境、如何使用Android功能和服务、以及如何为发布游戏做准备相关的指南。
当前SDK要求
- 当前UE版本:5.3
- Android Studio Version: Flamingo 2022.2.1 Patch 2 May 24, 2023
- Android SDK:
- 推荐版本:SDK 33
- 通过编译要求的最低版本:SDK 30
- 能在设备上发布所需的最低目标SDK版本:26
不同商城对于目标SDK最低版本的要求是不同的,可能与上文有所不同。
- NDK版本:r25b
- 编译工具:33.0.1
- Java运行时:OpenJDK 17.0.6 2023-01-17
- 要进AGD调试,需要AGDE v23.1.82+。
当前设备兼容性
The current version of Unreal Engine supports Android devices meeting the following specifications:
- Android 8或更高版本
- 64位Arm CPU
- 兼容的GPU
- Mali T8xx、G71、G72、G76、G77、G78和G71x系列
- Adreno 5xx、6xx或7xx系列
- PowerVR GM9xxx系列
- Xclipse 920
- 兼容的图形API
- OpenGL ES 3.2
- Vulkan 1.1(需要Android 10或更高版本的设备,以及兼容的驱动程序)
开始入门
设置Android SDK和NDK
如何为虚幻引擎设置你的Android开发环境
Android快速入门
Android平台的开发设置。
设置Android设备
了解如何设置Android设备以便开发虚幻引擎项目。
开发指南
使用 Google Play 成就
利用 Google Play 成就提升玩家粘着度。
在安卓上使用 Ad Mob 游戏内置广告
在安卓上使用 AdMob 游戏内置广告系统。
Android Manifest控制
设置及使用Android Mainfest文件。
使用安卓内购
利用内购为安卓游戏增加更多付费内容。
使用 Google Play Services 排行榜
在游戏中使用排行榜。
Android虚拟键盘
了解如何设置Android虚拟键盘以在UE5中使用。
Android开发参考
如何安装不同的Android SDK,设置环境变量,以及使用纹理格式。
Android Vulkan移动渲染器
介绍Vulkan兼容性以及如何在Android项目中使用移动渲染
设置安卓运行画面
安卓项目自定义可选运行画面设置的总览。
打包和发布
项目发布签名
为项目上架 Google Play 商店做好准备。
Google Play资产交付参考
有关Google PAD API的参考和实现指南
打包Android项目
介绍如何打包最终Android项目。
安卓配置规则系统
介绍如何在虚幻引擎项目中设置安卓配置规则系统。
关于Android项目的自定义设备描述和可扩展性
设备描述规则和可扩展性设置的参考。
调试
调试Android项目
了解如何使用Android Studio调试Android项目。
在Visual Studio中使用AGDE调试
使用AGDE在Visual Studio中调试Android项目
Android文件服务器
使用Android文件服务器代替ADB来推送和编辑虚幻引擎项目的文件。
优化
为Android创建捆绑的PSO缓存
为Android设备创建捆绑的PSO缓存的分步骤操作说明。
降低安卓二进制文件大小
了解如何缩小安卓平台项目的二进制文件。
class BpEncryptor : public ndk::BpCInterface<IEncryptor>
{
public:
virtual binder_status_t encrypt(char * src, int length, char* out, int &error) {
LOGI( "BpEncryptor: encrypt ");
binder_status_t stat = STATUS_OK;
AParcel* parcelIn;
stat = AIBinder_prepareTransaction(asBinder().get(), &parcelIn);
if (stat != STATUS_OK) return stat;
stat = AParcel_writeInt32(parcelIn, length);
if (stat != STATUS_OK) return stat;
stat = AParcel_writeCharArray(parcelIn, reinterpret_cast<const char16_t *>(src), length);
if (stat != STATUS_OK) return stat;
stat = AParcel_writeInt32(parcelIn, length);
if (stat != STATUS_OK) return stat;
ndk::ScopedAParcel parcelOut;
stat = AIBinder_transact(asBinder().get(), TRANSACTION_ENCRYPT, &parcelIn, parcelOut.getR(), 0 /*flags*/);
if (stat != STATUS_OK) return stat;
int32_t size = 0;
stat = AParcel_readInt32(parcelOut.get(), &size);
if (stat != STATUS_OK) return stat;
return stat;
}
virtual int decrypt(char * src, int length, char* out, int &error) override{
LOGI( "BpEncryptor: decrypt ");
ndk::ScopedAParcel parcelOut;
binder_status_t stat = STATUS_OK;
AParcel* parcelIn;
stat = AIBinder_prepareTransaction(asBinder().get(), &parcelIn);
if (stat != STATUS_OK) return stat;
stat = AIBinder_transact(asBinder().get(), TRANSACTION_DECRYPT, &parcelIn, parcelOut.getR(), 0 /*flags*/);
return stat;
}
};