找回密码
 立即注册
查看: 238|回复: 0

Unity exe程序背景透明化+鼠标穿透(转)

[复制链接]
发表于 2023-2-8 09:51 | 显示全部楼层 |阅读模式
Unity exe程序背景透明化+鼠标穿透
代码

1. shader:

Shader "Custom/MakeTransparent" {  Properties {    _MainTex ("Base (RGB)", 2D) = "white" {}    _TransparentColorKey ("Transparent Color Key", Color) = (0,1,0,1)    _TransparencyMargin ("Transparency Margin", Float) = 0.01   }  SubShader {    Pass {      Tags { "RenderType"="Opaque" }      LOD 200          CGPROGRAM      #pragma vertex VertexShaderFunction      #pragma fragment PixelShaderFunction          #include "UnityCG.cginc"      struct VertexData      {        float4 position : POSITION;        float2 uv : TEXCOORD0;      };      struct VertexToPixelData      {        float4 position : SV_POSITION;        float2 uv : TEXCOORD0;      };      VertexToPixelData VertexShaderFunction(VertexData input)      {        VertexToPixelData output;        output.position = UnityObjectToClipPos (input.position);        output.uv = input.uv;        return output;      }          sampler2D _MainTex;      float3 _TransparentColorKey;      float _TransparencyMargin;      float4 PixelShaderFunction(VertexToPixelData input) : SV_Target      {        float4 color = tex2D(_MainTex, input.uv);              float deltaR = abs(color.r - _TransparentColorKey.r);        float deltaG = abs(color.g - _TransparentColorKey.g);        float deltaB = abs(color.b - _TransparentColorKey.b);        if (deltaR < _TransparencyMargin && deltaG < _TransparencyMargin && deltaB < _TransparencyMargin)        {          return float4(0.0f, 0.0f, 0.0f, 0.0f);        }        return color;      }      ENDCG    }  }}2.C#:

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;    }    [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);    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]    private static extern int SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int cx, int cy,        int uFlags);    [DllImport("user32.dll")]    static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);    [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]    static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, byte bAlpha, int dwFlags);    [DllImport("User32.dll")]    private static extern bool SetForegroundWindow(IntPtr hWnd);    const int GWL_STYLE = -16;    const int GWL_EXSTYLE = -20;    const uint WS_POPUP = 0x80000000;    const uint WS_VISIBLE = 0x10000000;    const uint WS_EX_TOPMOST = 0x00000008;    const uint WS_EX_LAYERED = 0x00080000;    const uint WS_EX_TRANSPARENT = 0x00000020;    const int SWP_FRAMECHANGED = 0x0020;    const int SWP_SHOWWINDOW = 0x0040;    const int LWA_ALPHA = 2;    private IntPtr HWND_TOPMOST = new IntPtr(-1);    private IntPtr _hwnd;    void Start()    {#if !UNITY_EDITOR        MARGINS margins = new MARGINS() { cxLeftWidth = -1 };        _hwnd = GetActiveWindow();        int fWidth = Screen.width;        int fHeight = Screen.height;        SetWindowLong(_hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);        //SetWindowLong(_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT);//若想鼠标穿透,则将这个注释恢复即可        DwmExtendFrameIntoClientArea(_hwnd, ref margins);        SetWindowPos(_hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, SWP_FRAMECHANGED | SWP_SHOWWINDOW);         ShowWindowAsync(_hwnd, 3); //Forces window to show in case of unresponsive app    // SW_SHOWMAXIMIZED(3)#endif    }    void OnRenderImage(RenderTexture from, RenderTexture to)    {        Graphics.Blit(from, to, m_Material);    }}操作:

1. 新建Material(材质球),选择shader:


2. c#脚本挂在摄像机上,摄像机的Clear Flags选择Solid Color模式,脚本上挂载刚刚新建的材质球:


3. 摄像机的Background属性要和材质球的Transparent Color Key属性一致:




4. 最重要的一点!!!我这里的Unity开发版本为2019.4.2f1版本,2019以上的版本需要取消勾选一个属性,不然是没有效果的,若是2019以下的版本则可能不需要设置,题主在2018.3.8f1上就不需要设置,如图:




2019版本若是有这个设置,则必须要关闭,设置位置:
Edit——ProjectSettings——Player——ResolutionandPresentation——UseDXGIFlipModelSwapchainforD3D11
至于是什么原因,暂时还不了解,如果有同学知道,望能指教一二
发布效果如下:



PS:我这个程序是没有鼠标穿透的,C#脚本里有鼠标穿透的代码提示,注释取消一下即可

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-21 09:11 , Processed in 0.091503 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表