Unity 设置窗体透明

这篇博客介绍了如何在Unity中实现窗口透明、窗口置顶以及鼠标穿透功能。提供了三种不同的方法,包括各自的优缺点和关键代码。方法二被提到效果最佳,能消除边缘毛边。此外,还分享了一个无需编写代码的技巧,通过命令行参数来去掉窗口边框。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设置窗口透明、窗口置顶、鼠标穿透

   

方法一、

缺点:边缘不平滑,有毛边

参考博客:

1、https://alastaira.wordpress.com/2015/06/15/creating-windowless-unity-applications/

2、http://www.manew.com/thread-43230-1-1.html

3、https://blog.youkuaiyun.com/dark00800/article/details/70314432

关键代码

Shader "Custom/ChromakeyTransparent" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _TransparentColourKey ("Transparent Colour Key", Color) = (0,0,0,1)
        _TransparencyTolerance ("Transparency Tolerance", Float) = 0.01 
    }
    SubShader {
        Pass {
            Tags { "RenderType" = "Opaque" }
            LOD 200
         
            CGPROGRAM
 
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
 
            struct a2v
            {
                float4 pos : POSITION;
                float2 uv : TEXCOORD0;
            };
 
            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
 
            v2f vert(a2v input)
            {
                v2f output;
                output.pos = mul (UNITY_MATRIX_MVP, input.pos);
                output.uv = input.uv;
                return output;
            }
         
            sampler2D _MainTex;
            float3 _TransparentColourKey;
            float _TransparencyTolerance;
 
            float4 frag(v2f input) : SV_Target
            {
                // What is the colour that *would* be rendered here?
                float4 colour = tex2D(_MainTex, input.uv);
             
                // Calculate the different in each component from the chosen transparency colour
                float deltaR = abs(colour.r - _TransparentColourKey.r);
                float deltaG = abs(colour.g - _TransparentColourKey.g);
                float deltaB = abs(colour.b - _TransparentColourKey.b);
 
                // If colour is within tolerance, write a transparent pixel
                if (deltaR < _TransparencyTolerance && deltaG < _TransparencyTolerance && deltaB < _TransparencyTolerance)
                {
                    return float4(0.0f, 0.0f, 0.0f, 0.0f);
                }
 
                // Otherwise, return the regular colour
                return colour;
            }
            ENDCG
        }
    }
}
using System;
using System.Runtime.InteropServices;
using UnityEngine;
 
public class TransparentWindow : MonoBehaviour
{
    [SerializeField]
    private Material m_Material;
 
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }
 
    // Define function signatures to import from Windows APIs
 
    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();
 
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
     
    [DllImport("Dwmapi.dll")]
    private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
 
 
    // Definitions of window styles
    const int GWL_STYLE = -16;
    const uint WS_POPUP = 0x80000000;
    const uint WS_VISIBLE = 0x10000000;
 
    void Start()
    {
        #if !UNITY_EDITOR
        var margins = new MARGINS() { cxLeftWidth = -1 };
 
        // Get a handle to the window
        var hwnd = GetActiveWindow();
 
        // Set properties of the window
        // See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx
        SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
         
        // Extend the window into the client area
        See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa969512%28v=vs.85%29.aspx 
        DwmExtendFrameIntoClientArea(hwnd, ref margins);
        #endif
    }
 
    // Pass the output of the camera to the custom material
    // for chroma replacement
    void OnRenderImage(RenderTexture from, RenderTexture to)
    {
        Graphics.Blit(from, to, m_Material);
    }
}

下面是改进版,添加窗口置顶和鼠标穿透,不过依然存在毛边现象,shader还是用上面的

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

 
public class TransparentWindow :MonoBehaviour
{

    [SerializeField]
    public Material m_Material;

    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }

    // Define function signatures to import from Windows APIs

    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();

    [DllImport("user32.dll")]
    private static extern uint SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

    [DllImport("Dwmapi.dll")]
    private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);

    [DllImport("user32.dll")]
    private static extern uint GetWindowLong(IntPtr hwnd,int nIndex);
    [DllImport("user32.dll")]
    private static extern int SetLayeredWindowAttributes(IntPtr hwnd,int crKey,int bAlpha,int dwFlags);

    /// <summary>   
    /// 窗口置顶
    /// </summary>   
    /// <returns></returns>
    [DllImport("user32.dll")]
    private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
    /// <summary>   
    /// 得到当前活动的窗口   
    /// </summary>   
    /// <returns></returns>   
    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();


   

const uint LWA_COLORKEY = 0x1;
    // Definitions of window styles
    const int GWL_STYLE = -16;
    const uint WS_POPUP = 0x80000000;
    const uint WS_VISIBLE = 0x10000000;

   

    private const uint WS_EX_LAYERED = 0x80000;
    private const int WS_EX_TRANSPARENT = 0x20;
 
    private const int GWL_EXSTYLE = (-20);
    private const int LWA_ALPHA = 0x2;
    IntPtr hwnd;
    void Start()
    {
        Application.runInBackground=true;
       var margins = new MARGINS() { cxLeftWidth = -1
Unity中实现窗体透明效果通常涉及到几个关键步骤,包括创建透明材质、调整摄像机设置以及挂载特定脚本。以下是详细的实现方法: 1. **创建透明材质** 首先,需要新建一个材质(Material),并为其指定一个支持透明度的Shader。可以选择Unity内置的Shader,如`Standard`或`Unlit/Transparent`,也可以使用自定义的Shader来实现更精细的透明效果。如果使用自定义Shader,确保其具备处理透明通道的能力。 2. **配置摄像机设置** 将摄像机的`Clear Flags`设置为`Solid Color`,并将`Background`颜色设置为与材质的透明颜色相同(通常为透明色或与模型边缘相近的颜色),以避免出现明显的毛边[^1]。这一步是确保透明效果能够正确渲染的关键。 3. **挂载脚本与组件** 创建一个名为`TransparentWindow`的脚本,并将其挂载到摄像机上。该脚本应包含对透明材质的引用,并在渲染时应用该材质以实现透明效果。以下是一个简单的脚本示例: ```csharp using UnityEngine; public class TransparentWindow : MonoBehaviour { public Material transparentMaterial; private void OnRenderImage(RenderTexture source, RenderTexture destination) { if (transparentMaterial != null) { Graphics.Blit(source, destination, transparentMaterial); } else { Graphics.Blit(source, destination); } } } ``` 4. **调整透明颜色与边缘效果** 为了获得最佳的透明效果,建议将摄像机背景色与材质的透明颜色设置为一致,并尽量选择与模型边缘颜色相近的颜色。这样可以减少透明边缘的锯齿感,使透明效果更加自然。 5. **测试与调试** 在完成上述步骤后,运行场景并检查透明窗体的效果。如果发现透明区域有异常显示,可以尝试调整材质的透明度、摄像机的背景颜色或Shader的参数,以达到预期的视觉效果。 通过以上步骤,可以在Unity中较为完整地实现窗体透明效果,适用于需要透明背景的UI或特殊视觉需求的场景。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值