Unity-Demo游戲?qū)崿F(xiàn)桌面小寵物
看到網(wǎng)上有用Unity做的桌面小寵物,就自己搜了些資料自己做了一個小Demo。
核心功能實現(xiàn)
簡單說一下思路,有一個腳本跟一個Shader,通過腳本和Shader負責將Unity運行時的背景調(diào)成透明色。這個是通過調(diào)顏色來進行了。具體原理也不清楚,查了查資料大概是這樣
窗口透明化與無邊框
- 通過Windows API調(diào)用
SetWindowLong
和DwmExtendFrameIntoClientArea
實現(xiàn)透明背景和隱藏邊框,需在相機設(shè)置中將Clear Flags
設(shè)為Solid Color
且透明度為01。 - 注意:背景色需與模型邊緣顏色相近以避免毛邊(如0x00BGR格式的COLORREF值)2。
- 通過Windows API調(diào)用
交互邏輯
- 點擊穿透:通過檢測鼠標坐標與模型碰撞器實現(xiàn)交互(如點擊播放撓癢動畫)15。
- 拖拽限制:動態(tài)計算模型碰撞器與屏幕邊緣距離,使用
Mathf.Clamp
限制移動范圍2。
代碼部分
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 } } }
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(材質(zhì)球),選擇剛建立的Shader:
2.將剛寫的C#腳本掛在攝像機上,攝像機的Clear Flags模式選擇Solod Color,并將剛建立的材質(zhì)球掛在腳本上。
3.攝像機的Background屬性要和材質(zhì)球的Transparent Color Key屬性一致:
4.這里要注意一個點,unity19以上的版本需要設(shè)置一個東西。在playerSetting中將這個UseDXGIFlipModelSwapchainforD3D11取消勾選。
這樣就可以實現(xiàn)窗口透明了,然后在場景里加一個模型跟動作就好啦
總結(jié)
到此這篇關(guān)于Unity-Demo游戲?qū)崿F(xiàn)桌面小寵物的文章就介紹到這了,更多相關(guān)Unity-Demo桌面小寵物內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# KeyUp事件中MessageBox的回車(Enter)鍵回調(diào)問題解決方案
這篇文章主要介紹了C# KeyUp事件中MessageBox的回車(Enter)鍵回調(diào)問題解決方案,需要的朋友可以參考下2014-07-07c# DataView.ToTable()方法 去除表的重復項問題
這篇文章主要介紹了c# DataView.ToTable()方法 去除表的重復項問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12c#數(shù)據(jù)綁定之刪除datatable數(shù)據(jù)示例
這篇文章主要介紹了c#刪除datatable數(shù)據(jù)示例,需要的朋友可以參考下2014-04-04