目前接触项目是实时竞技项目,即时性要求较高,因为是内网所以直接使用了UPD每帧同步物理运算得到的位置、旋转数据,但是体验过程中发现有明显卡顿,一番排查发现是quest接入wifi网络ping值始终有高延迟波动,经过查阅文档发现是Android的功耗优化降低了wlan频率,使用WIFI_MODE_FULL_LOW_LATENCY 或 WIFI_MODE_FULL_HIGH_PERF可以让wlan处于高性能或低延迟模式,网络基本能很好的保持在3ms左右延迟
以下为调用实现代码过程
1.创建插件封装android调用
2.插件build.cs代码
注:需要使用JNI一定要加上PrivateDependencyModuleNames.AddRange(new string[] { "Launch" });
// // Copyright 2022-2023 Jiangcongcong. All Rights Reserved.
using UnrealBuildTool;
using System.IO;
public class PluginName : ModuleRules
{
public PluginName(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
if (Target.Platform == UnrealTargetPlatform.Android){
PrivateDependencyModuleNames.AddRange(new string[] { "Launch" });
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("AndroidPlugin", Path.Combine(PluginPath, "PluginName_APL.xml"));
}
PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"CoreUObject",
"RHI",
"Engine",
"Slate",
"SlateCore",
"RenderCore",
// ... add other public dependencies that you statically link with here ...
"Sockets",
"Networking"
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"RHI",
"Engine",
"Slate",
"SlateCore",
"RenderCore"
// ... add private dependencies that you statically link with here ...
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}
3.C++调用AndroidAPI函数库
.h
#pragma once
// import
#include "CoreMinimal.h"
#if PLATFORM_ANDROID
#include "Runtime/Launch/Public/Android/AndroidJNI.h"
#include "Runtime/ApplicationCore/Public/Android/AndroidApplication.h"
#endif
#include "Kismet/BlueprintFunctionLibrary.h"
#include "PluginNameBPLibrary.generated.h"
UCLASS()
class UPluginNameBPLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
UFUNCTION(BlueprintCallable)
static void SetWifiMode(FString value);
};
.cpp
#include "PluginNameBPLibrary.h"
UPluginNameBPLibrary::UPluginNameBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UPluginNameBPLibrary::SetWifiMode(FString value)
{
#if PLATFORM_ANDROID
if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
{
bool bIsOptional = false;
jstring info_content = Env->NewStringUTF(TCHAR_TO_UTF8(*value));
static jmethodID MethonId_Test = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "SetNetWifiMode", "(Ljava/lang/String;)V", bIsOptional);
FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, MethonId_Test, info_content);
}
#endif
}
4.Android插件部分代码,直接在APL.xml中插入~因为不想配置安卓开发环境去打包jar或者aar
,如果函数里面有<,>等符号,需要将代码使用<![CDATA[ code]]> 包含起来
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
<init>
<log text="log文本"/>
</init>
<resourceCopies>
<copyFile src = "$S(PluginDir)/../../Test.jar" dst = "$S(BuildDir)/libs/Test.jar" />
</resourceCopies>
<gameActivityImportAdditions>
<insert>
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.content.Context;
</insert>
</gameActivityImportAdditions>
<gameActivityClassAdditions>
<insert>
<![CDATA[
// 注册WifiLock
private WifiManager wifiManager;
private WifiLock wifiLock;
public void SetNetWifiMode(String info) {
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
int i = Integer.parseInt(info);
if (i==1){
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "LowLatency");
wifiLock.acquire();
}else if(i==3){
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "FullHigh");
wifiLock.acquire();
}else if(i==2){
wifiLock.release();
}
}
]]>
</insert>
</gameActivityClassAdditions>
</root>
5.apl.xml字段说明
解释:基于XML的一种语法,编写规则参考 Engine/Source/Programs/UnrealBuildTool/System/UnrealPluginLanguage.cs
感兴趣可以搜索unreal UPL以及安卓开发了解更多
init | 初始化时调用 |
resourceCopies | 在NDK之后复制文件,$S(PluginDir)为xml所在目录,$S(BuildDir)为Intermediate/Android/APK |
gameActivityImportAdditions | 填写java导入包的代码 |
gameActivityClassAdditions | 编写需要给C++调用的java代码 |
buildGradleAdditions | 编写需要在BuildGradle中增加的代码 |