16人参与 • 2025-08-17 • 游戏引擎
看到网上有用unity做的桌面小宠物,就自己搜了些资料自己做了一个小demo。
简单说一下思路,有一个脚本跟一个shader,通过脚本和shader负责将unity运行时的背景调成透明色。这个是通过调颜色来进行了。具体原理也不清楚,查了查资料大概是这样
窗口透明化与无边框
setwindowlong
和dwmextendframeintoclientarea
实现透明背景和隐藏边框,需在相机设置中将clear flags
设为solid color
且透明度为01。交互逻辑
mathf.clamp
限制移动范围2。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 } } }
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模式选择solod color,并将刚建立的材质球挂在脚本上。
3.摄像机的background属性要和材质球的transparent color key属性一致:
4.这里要注意一个点,unity19以上的版本需要设置一个东西。在playersetting中将这个usedxgiflipmodelswapchainford3d11取消勾选。
这样就可以实现窗口透明了,然后在场景里加一个模型跟动作就好啦
到此这篇关于unity-demo游戏实现桌面小宠物的文章就介绍到这了,更多相关unity-demo桌面小宠物内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论