设置窗口透明、窗口置顶、鼠标穿透
方法一、
缺点:边缘不平滑,有毛边
参考博客:
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.csdn.net/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 = -