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中增加的代码

相关推荐

  1. UE4 quest3平台网络稳定问题排查解决

    2024-03-30 09:44:03       29 阅读
  2. 解决PyTorch ONNX模型每次输出结果稳定问题

    2024-03-30 09:44:03       42 阅读
  3. selenium元素单击稳定解决方法

    2024-03-30 09:44:03       40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-30 09:44:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-30 09:44:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-30 09:44:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-30 09:44:03       20 阅读

热门阅读

  1. vscode插件

    2024-03-30 09:44:03       19 阅读
  2. Python数据库编程全指南SQLite和MySQL实践

    2024-03-30 09:44:03       19 阅读
  3. 【统计】什么事 R 方

    2024-03-30 09:44:03       20 阅读
  4. 机器学习概念、步骤、分类和实践

    2024-03-30 09:44:03       18 阅读
  5. openGauss JDBC客户端负载均衡与读写分离

    2024-03-30 09:44:03       20 阅读