You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity切换分辨率后systemWidth/systemHeight未更新的解决方法求助

问题解决:Unity中Display.systemWidth/Height未随系统显示设置更新

你通过ChangeDisplaySettingsEx成功切换了显示分辨率(将1920×1080转为1080×1920,旋转90度),但Unity的Display.systemWidth和systemHeight没有同步更新,这是因为Unity不会自动实时监听系统显示设置的变化,需要手动触发刷新或者通过正确的方式获取最新值。以下是几种可行的解决方法:

方法1:手动调用Display.ReloadDisplayStats()

Unity提供了Display.ReloadDisplayStats()方法,用来强制重新读取系统显示设备的状态,更新Display类的相关属性。你需要在调用ChangeDisplaySettingsEx之后,等待系统设置生效,再调用这个方法。

修改你的代码,添加等待和刷新逻辑:

DISP_CHANGE iRet = NativeMethods.ChangeDisplaySettingsEx(
    d.DeviceName, ref dm, IntPtr.Zero,
    DisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);

// 确认显示设置切换成功后,强制刷新Unity显示数据
if(iRet == DISP_CHANGE.SUCCESSFUL)
{
    Display.ReloadDisplayStats();
    // 等待一帧确保Unity完成数据更新
    yield return null;
    
    if (Display.displays.Length > 1)
    {
        UnityEngine.Debug.LogError(Display.displays[1].systemWidth + " " + Display.displays[1].systemHeight);
        UnityEngine.Debug.LogError(Display.displays[1].renderingWidth + " " + Display.displays[1].renderingHeight);
    }
}

注意:这段代码需要在MonoBehaviour的协程中执行,因为yield return null需要协程环境。如果你的代码不在协程里,可以通过添加临时协程或延迟调用实现等待。

方法2:监听DisplayManager显示更新事件(Unity 2020+)

从Unity 2020版本开始,可通过DisplayManager的displaysUpdated事件监听显示设备变化,在回调中获取最新属性:

void Start()
{
    // 注册显示更新事件
    DisplayManager.displaysUpdated += OnDisplaysUpdated;
}

void OnDisplaysUpdated()
{
    if (Display.displays.Length > 1)
    {
        UnityEngine.Debug.LogError(Display.displays[1].systemWidth + " " + Display.displays[1].systemHeight);
        UnityEngine.Debug.LogError(Display.displays[1].renderingWidth + " " + Display.displays[1].renderingHeight);
    }
}

void OnDestroy()
{
    // 取消事件注册,避免内存泄漏
    DisplayManager.displaysUpdated -= OnDisplaysUpdated;
}

调用ChangeDisplaySettingsEx后,系统显示设置生效时会触发该事件,此时获取的Display属性即为最新值。

方法3:直接通过原生接口读取最新值

如果上述方法不生效,可在切换显示设置后,再次调用EnumDisplaySettings直接读取系统最新的分辨率,绕过Unity的Display缓存:

DISP_CHANGE iRet = NativeMethods.ChangeDisplaySettingsEx(
    d.DeviceName, ref dm, IntPtr.Zero,
    DisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);

if(iRet == DISP_CHANGE.SUCCESSFUL)
{
    // 重新读取系统最新显示设置
    NativeMethods.EnumDisplaySettings(d.DeviceName, NativeMethods.ENUM_CURRENT_SETTINGS, ref dm);
    int currentWidth = dm.dmPelsWidth;
    int currentHeight = dm.dmPelsHeight;
    UnityEngine.Debug.LogError("最新分辨率:" + currentWidth + " " + currentHeight);
    
    // 可选:手动同步Unity渲染分辨率
    if (Display.displays.Length > 1)
    {
        Display.displays[1].SetRenderingResolution(currentWidth, currentHeight);
    }
}

这种方式直接从系统获取数据,不受Unity缓存影响,还能手动对齐Unity的渲染分辨率。

注意事项

  • 调用ChangeDisplaySettingsEx后,系统需要短暂时间应用设置,不要立即读取值,需等待或通过返回值确认成功后再操作。
  • 不同Unity版本对Display类的处理有差异,建议参考对应版本官方文档确认API可用性。

内容的提问来源于stack exchange,提问作者SoulSystem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 21:37:44