UE4 quest3平台网络不稳定问题排查及解决

目前接触项目是实时竞技项目,即时性要求较高,因为是内网所以直接使用了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中增加的代码

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值