【多媒体交互】透明无边框窗口

技术应用方向

  • 桌面宠物
  • 透明屏互动

核心技术点

  • 窗体隐藏
  • 背景透明
  • 穿透点击

脚步实现步骤

  • 使用Windows API,DllImport引入user32.dll、dwmapi.dll中的相关函数
  • 在Unity中获取当前窗口句柄【GetActiveWindow
  • 自定义边框结构【MARGINS】
    • 窗体阴影:【1,1,1,1】
    • 顶栏透明:【0,0,30,0】
    • 全透明边:【-1,-1,-1,-1】
  • 将窗口边框扩展到客户区域【DwmExtendFrameIntoClientArea
  • 将窗口样式设置为分层和透明【SetWindowLong
  • 设置透明颜色或整体透明度【SetLayeredWindowAttributes
  • 将窗口位置设置为始终置顶【SetWindowPos
  • 允许应用在后台运行【Application.runInBackground = true】

Unity场景设置

  • 将相机【Camera】的背景类型(Clear Flags)设置为Solid Color,并将颜色设置为完全透明(alpha=0)
  • 在相机的设置中,可能需要开启HDR(高动态范围)和关闭MSAA(多重采样抗锯齿)以避免透明边缘问题
  • 【Project Setting】【Resolution and Presentation】设置
    • 开启Fullscreen Window
    • 开启Resizable Window
    • 开启Visible In Background
    • 关闭Use DXGI flip model swapchain for D3D11
csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
 
public class WindowTransparent : MonoBehaviour
{
    // 定义一个结构来存储窗口边框的边距大小
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }
 
    // 导入 user32.dll 以获取活动窗口句柄 (HWND)
    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();
 
    // 导入 Dwmapi.dll 以将窗口边框扩展到客户区域
    [DllImport("Dwmapi.dll")]
    private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
 
    // 导入 user32.dll 以修改窗口属性
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
 
    // 导入 user32.dll 以设置窗口位置
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
 
    // 导入 user32.dll 以设置分层窗口属性 (透明度)
    [DllImport("user32.dll")]
    static extern int SetLayeredWindowAttributes(IntPtr hWnd, uint crKey, byte bAlpha, uint dwFlags);
 
    // 代码中使用的常量和变量
    const int GWL_EXSTYLE = -20;  // 修改窗口样式的索引
    const uint WS_EX_LAYERED = 0x00080000;  // 分层窗口的扩展样式
    const uint WS_EX_TRANSPARENT = 0x00000020;  // 透明窗口的扩展样式
    static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);  // 窗口插入位置(始终置顶)
    const uint LWA_COLORKEY = 0x00000001;  // 设置颜色键的标志(用于透明度)
    private IntPtr hWnd;  // 活动窗口的句柄
 
    private void Start()
    {
#if !UNITY_EDITOR
        // 获取活动窗口的句柄
        hWnd = GetActiveWindow();
 
        // 创建一个边距结构来定义边框大小
        MARGINS margins = new MARGINS { cxLeftWidth = -1 };
 
        // 将窗口边框扩展到客户区域(玻璃效果)
        DwmExtendFrameIntoClientArea(hWnd, ref margins);
 
        // 将窗口样式设置为分层和透明
        SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED);
 
        // 设置窗口颜色键(用于透明度)
        SetLayeredWindowAttributes(hWnd, 0, 0, LWA_COLORKEY);
 
        // 将窗口位置设置为始终置顶
        SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, 0);
#endif
 
        // 允许应用在后台运行
        Application.runInBackground = true;
    }
}
相关推荐
CreasyChan1 小时前
Unity GC实战优化总结
unity·c#
玩泥巴的1 小时前
深入理解飞书 Webhook 签名验证:一次踩坑到填坑的完整记录
c#·.net·飞书
切糕师学AI4 小时前
.Net 中的 ActivatorUtilitiesConstructor 特性
.net
FuckPatience5 小时前
C# SqlSugar+SQLite: 无法加载 DLL“e_sqlite3”: 找不到指定的模块
开发语言·c#
HelloRevit5 小时前
Windows Server SMB 共享文件 回收站
windows·c#
曹牧6 小时前
C#:ToDouble
开发语言·c#
yongui478346 小时前
使用C#实现Excel实时读取并导入SQL数据库
数据库·c#·excel
阿蒙Amon7 小时前
C#每日面试题-简述匿名方法
java·面试·c#
波波0077 小时前
C# 中静态类的正确与错误用法
c#