如何为移动设备设置可用的最高刷新率(非目标帧率)
解决方案:让Unity应用自动使用Android设备最高刷新率
核心思路
通过调用Android原生API获取设备支持的所有刷新率,筛选出最大值后,强制应用窗口使用该刷新率,同时匹配Unity的帧率设置,避免因系统刷新率限制导致的掉帧问题。
具体实现步骤(C#代码)
在Unity项目中添加以下代码,建议放在启动场景的单例脚本中,仅在Android平台执行:
using UnityEngine; public class RefreshRateManager : MonoBehaviour { void Awake() { #if UNITY_ANDROID && !UNITY_EDITOR SetMaxRefreshRate(); #endif } private void SetMaxRefreshRate() { try { // 获取Android系统的DisplayManager AndroidJavaClass displayManagerClass = new AndroidJavaClass("android.hardware.display.DisplayManager"); AndroidJavaObject context = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject displayManager = context.Call<AndroidJavaObject>("getSystemService", "display"); // 获取默认Display的所有支持模式 AndroidJavaObject[] displayModes = displayManager.Call<AndroidJavaObject[]>("getSupportedDisplayModes", 0); // 0代表默认显示屏 float maxRefreshRate = 60f; foreach (AndroidJavaObject mode in displayModes) { float refreshRate = mode.Call<float>("getRefreshRate"); if (refreshRate > maxRefreshRate) { maxRefreshRate = refreshRate; } } // 设置Unity的目标帧率为最高刷新率 Application.targetFrameRate = (int)maxRefreshRate; // 强制应用窗口使用最高刷新率的显示模式 AndroidJavaObject window = context.Call<AndroidJavaObject>("getWindow"); AndroidJavaObject layoutParams = window.Call<AndroidJavaObject>("getAttributes"); // 遍历找到对应最高刷新率的modeId int targetModeId = -1; foreach (AndroidJavaObject mode in displayModes) { if (mode.Call<float>("getRefreshRate") == maxRefreshRate) { targetModeId = mode.Call<int>("getModeId"); break; } } if (targetModeId != -1) { // Android 12+ 用setPreferredDisplayModeId,旧版本尝试设置refreshRate参数 if (AndroidOSVersionIsAtLeast(31)) { layoutParams.Call("setPreferredDisplayModeId", targetModeId); } else { layoutParams.SetField("refreshRate", maxRefreshRate); } window.Call("setAttributes", layoutParams); } } catch (System.Exception e) { Debug.LogError("设置最高刷新率失败: " + e.Message); // 失败时 fallback 到默认60帧 Application.targetFrameRate = 60; } } private bool AndroidOSVersionIsAtLeast(int apiLevel) { AndroidJavaClass buildClass = new AndroidJavaClass("android.os.Build$VERSION"); int currentApi = buildClass.GetStatic<int>("SDK_INT"); return currentApi >= apiLevel; } }
注意事项
- 该代码仅在Android平台生效,编辑器下不会执行
- 无需额外权限,应用仅能修改自身窗口的刷新率设置,不会影响系统全局设置
- 部分旧设备可能不支持动态切换刷新率,此时会自动 fallback 到60帧的默认设置
- 若设备最高刷新率为120Hz,Unity的
Application.targetFrameRate会被设为120,确保渲染帧率与屏幕刷新率同步
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

