最近在做展厅透明柜项目,发布的exe需要把窗体变为透明的,还需要在右上角增加最小化,最大化以及还原窗口大小的按钮,废话不多说,先看下效果
以下为操作方法:
1.首先新建一个叫TransparentWindow的CS脚本,输入如下代码:
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 };
var hwnd = GetActiveWindow();
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
DwmExtendFrameIntoClientArea(hwnd, ref margins);
#endif
}
void OnRenderImage(RenderTexture from, RenderTexture to)
{
Graphics.Blit(from, to, m_Material);
}
}
2.然后新建一个叫ChromakeyTransparent的Shader:
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 = UnityObjectToClipPos(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
}
}
}
3.新建一个材质,选择我们刚刚写好的Shader,将TransparentWindow挂载到摄像机上,摄像机的Clear Flags选择Solid Color,Background选择和材质的Transparent Color Key相同的颜色(建议选择与模型边缘颜色相近的颜色,不然会出现较明显的毛边),将材质拖拽给TransparentWindow的Material变量。


4.打包运行即可发现程序变透明了,在编辑器内是黑色显示
程序最大化最小化等操作直接贴代码?
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public class WindowMaxAndMin : MonoBehaviour
{
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern uint SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
const int SW_SHOWMINIMIZED = 2; //{最小化, 激活}
const int SW_SHOWMAXIMIZED = 3;//最大化
const int SW_SHOWRESTORE = 1;//还原
private const int GWL_EXSTYLE = (-20);
private const int WS_EX_TRANSPARENT = 0x20;
private const uint WS_EX_LAYERED = 0x80000;
public void OnClickMinimize()
{ //最小化
ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
}
public void OnClickMaximize()
{
//最大化
ShowWindow(GetForegroundWindow(), SW_SHOWMAXIMIZED);
}
public void OnClickRestore()
{
//还原
ShowWindow(GetForegroundWindow(), SW_SHOWRESTORE);
}
public void OnClickQuit()
{
//退出
Application.Quit();
}
/// <summary>
/// 鼠标穿透
/// </summary>
public void OnClickMouse()
{
SetWindowLong(GetActiveWindow(), GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
}
//测试
public void OnGUI()
{
if (GUI.Button(new Rect(100, 100, 200, 100), "最大化"))
OnClickMaximize();
if (GUI.Button(new Rect(100, 300, 200, 100), "最小化"))
OnClickMinimize();
if (GUI.Button(new Rect(100, 500, 200, 100), "窗口还原"))
OnClickRestore();
if (GUI.Button(new Rect(100, 700, 200, 100), "退出"))
OnClickQuit();
if (GUI.Button(new Rect(100, 900, 200, 100), "鼠标穿透"))
OnClickMouse();
}
}
注:相关demo链接https://download.csdn.net/download/qq_33155437/22030431
demo使用的是Unity2017.4制作,Unity2018版本制作一样,Unity2019需要在Player setting勾上“Render Over Native UI”
|