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

Unity中屏幕空间、窗口空间、显示器空间的区别及坐标转换方案咨询

Unity 屏幕空间转显示器空间实现方案

Unity默认的屏幕空间以应用窗口左下角为(0,0),要转换为全局显示器坐标,只需要叠加应用窗口在显示器上的全局位置偏移,同时适配系统DPI缩放即可。多显示器场景下只需额外获取窗口所属显示器的坐标基准即可适配。

Windows 平台可靠实现

该方案直接调用Win32原生API,兼容性覆盖Win10/Win11全版本,支持多显示器场景:

using System;
using System.Runtime.InteropServices;
using UnityEngine;

public static class ScreenToMonitorConverter
{
    // Win32 API 定义
    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();
    
    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    
    [DllImport("user32.dll")]
    private static extern uint GetDpiForWindow(IntPtr hWnd);

    /// <summary>
    /// 输入Unity屏幕空间坐标,返回全局显示器空间坐标(左上角为(0,0))
    /// </summary>
    /// <param name="unityScreenPos">Unity屏幕空间坐标,Y轴向上</param>
    /// <returns>全局显示器坐标,Y轴向下</returns>
    public static Vector2 ConvertToMonitorSpace(Vector2 unityScreenPos)
    {
        IntPtr windowHandle = GetActiveWindow();
        GetWindowRect(windowHandle, out RECT windowRect);
        uint dpi = GetDpiForWindow(windowHandle);
        // 计算DPI缩放系数,默认96DPI为100%缩放
        float dpiScale = dpi / 96f;
        
        // Win32窗口bottom为左下角Y坐标
        int windowBottomY = windowRect.bottom;
        int windowLeftX = windowRect.left;

        // 叠加偏移,适配DPI
        float monitorX = windowLeftX + unityScreenPos.x * dpiScale;
        // Unity屏幕坐标Y向上,Win32显示器坐标Y向下,做翻转计算
        float monitorY = windowBottomY - unityScreenPos.y * dpiScale;

        return new Vector2(monitorX, monitorY);
    }
}
  • 如果需要显示器坐标以左下角为基准,只需将返回值的Y坐标替换为 当前显示器总高度 - monitorY 即可。
  • 多显示器场景下,返回的坐标是跨所有显示器的全局坐标,比如副显示器在主显示器右侧,那么副显示器的X坐标起始值等于主显示器的宽度。

跨平台适配思路

如果需要兼容macOS、Linux系统,逻辑和Windows完全一致,只需替换为对应平台的原生API调用即可:

  • macOS:调用Cocoa框架的NSWindow相关接口,获取当前应用窗口的全局frame、系统缩放系数,做坐标偏移计算。
  • Linux:调用X11或Wayland协议的对应接口,获取窗口位置和DPI参数后完成转换。

注意事项

  • 全屏模式下应用窗口会铺满对应显示器,可直接用Display.activeDisplay.bounds参数简化计算,无需调用原生API。
  • 若输入坐标是3D世界空间的UI坐标,需先调用对应相机的Camera.WorldToScreenPoint()方法转换为Unity屏幕空间坐标,再传入转换函数。
  • 缩放系数适配要以窗口所属显示器的DPI为准,不要用系统全局DPI,避免多显示器不同缩放比例时计算错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:15:04