虚幻引擎 支持将项目发布到 安卓(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,设置环境变量,以及使用纹理格式。
介绍Vulkan兼容性以及如何在Android项目中使用移动渲染
打包和发布
调试
了解如何使用Android Studio调试Android项目。
使用AGDE在Visual Studio中调试Android项目
使用Android文件服务器代替ADB来推送和编辑虚幻引擎项目的文件。
优化
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;
}
};