如何在Unity中制作透明窗口?现有代码配置运行后未生效求解决方案
透明窗口失效解决方案
前置配置检查
- 打开Unity Player设置,进入「Resolution and Presentation」栏,勾选「Allow Transparent Window」(Unity 2021及以上版本提供该选项,旧版本需额外移除窗口边框样式)
- 相机参数确认:清除标志设置为「Solid Color」,背景色设为RGBA(0,0,0,0),关闭相机HDR功能,禁用深度纹理输出
- 渲染管线配置:将渲染路径设置为Forward,所有需要显示的透明材质需开启Alpha Blend模式,关闭深度写入
代码问题修正
你当前的代码缺少窗口扩展样式配置、MARGINS结构定义可能存在错误,调用顺序也不符合DWM透明渲染的要求,修正后的完整代码如下:
首先是正确的Win32 API及结构体声明:
using System; using System.Runtime.InteropServices; using UnityEngine; public struct MARGINS { public int cxLeftWidth; public int cxRightWidth; public int cyTopHeight; public int cyBottomHeight; } public static class Win32API { public const int GWL_STYLE = -16; public const int GWL_EXSTYLE = -20; public const uint WS_CAPTION = 0x00C00000; public const uint WS_EX_LAYERED = 0x00080000; public const uint WS_EX_TRANSPARENT = 0x00000020; public const uint WS_EX_COMPOSITED = 0x02000000; public const int LWA_ALPHA = 0x00000002; public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); public const uint SWP_FRAMECHANGED = 0x0020; public const uint SWP_SHOWWINDOW = 0x0040; [DllImport("user32.dll")] public static extern IntPtr GetActiveWindow(); [DllImport("user32.dll")] public static extern uint GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] public static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong); [DllImport("user32.dll")] public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey, byte bAlpha, uint dwFlags); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("dwmapi.dll")] public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset); }
然后是调用逻辑,建议放在Start生命周期中执行:
void Start() { int fWidth = Screen.width; int fHeight = Screen.height; var hwnd = Win32API.GetActiveWindow(); // 移除默认窗口标题栏样式 uint oldStyle = Win32API.GetWindowLong(hwnd, Win32API.GWL_STYLE); uint newStyle = oldStyle & ~Win32API.WS_CAPTION; Win32API.SetWindowLong(hwnd, Win32API.GWL_STYLE, newStyle); // 添加透明所需的扩展窗口样式 uint oldExStyle = Win32API.GetWindowLong(hwnd, Win32API.GWL_EXSTYLE); uint newExStyle = oldExStyle | Win32API.WS_EX_LAYERED | Win32API.WS_EX_COMPOSITED; // 如需鼠标穿透则保留WS_EX_TRANSPARENT,不需要可删除 // newExStyle |= Win32API.WS_EX_TRANSPARENT; Win32API.SetWindowLong(hwnd, Win32API.GWL_EXSTYLE, newExStyle); // 扩展DWM玻璃区域到整个窗口 var margins = new MARGINS() { cxLeftWidth = -1 }; Win32API.DwmExtendFrameIntoClientArea(hwnd, ref margins); // 设置分层窗口属性,这里保留完全不透明的全局alpha,仅使用内容本身的alpha通道 Win32API.SetLayeredWindowAttributes(hwnd, 0, 255, Win32API.LWA_ALPHA); // 应用窗口位置和层级设置 Win32API.SetWindowPos(hwnd, Win32API.HWND_TOPMOST, 0, 0, fWidth, fHeight, Win32API.SWP_FRAMECHANGED | Win32API.SWP_SHOWWINDOW); }
额外注意事项
- 打包后测试效果,编辑器下运行可能无法正确触发透明效果
- 系统需开启Aero效果(Win7及以上系统默认开启,Win10/11无需额外配置)
内容的提问来源于stack exchange,提问作者warriorforce
相关产品推荐
相关产品推荐

