Doris232 发表于 2022-6-1 12:48

使用Unity制作一个Windows桌面宠物

示意

如下图中的狐狸,鼠标左键按住可拖动,鼠标右键按住可调整大小,鼠标左键点击可随机播放一个动作。

桌宠.gif

思路

主要是2点

[*]让程序背景透明
参考文章:Unity 制作萌系live2d桌宠:屏幕自适应+交互
将TablePetBackSample.cs挂在一个GameObject上。
将MainCamera的ClearFlags改为SolidColor,Background的颜色改为透明:000000
using UnityEngine;using System;// 为了使用属性:DllImportusing System.Runtime.InteropServices;public class TablePetBackSample : MonoBehaviour{    private int currentX;    private int currentY;    #region Win函数常量    private struct MARGINS    {      public int cxLeftWidth;      public int cxRightWidth;      public int cyTopHeight;      public int cyBottomHeight;    }        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);        static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);        static extern int GetWindowLong(IntPtr hWnd, int nIndex);        static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);        static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);    private const int GWL_EXSTYLE = -20;    private const int GWL_STYLE = -16;    private const int WS_EX_LAYERED = 0x00080000;    private const int WS_BORDER = 0x00800000;    private const int WS_CAPTION = 0x00C00000;    private const int SWP_SHOWWINDOW = 0x0040;    private const int LWA_COLORKEY = 0x00000001;    private const int LWA_ALPHA = 0x00000002;    private const int WS_EX_TRANSPARENT = 0x20;    #endregion    private IntPtr hwnd;    void Awake()    {      var productName = Application.productName;#if UNITY_EDITOR#else      hwnd = FindWindow(null, productName);      int intExTemp = GetWindowLong(hwnd, GWL_EXSTYLE);      SetWindowLong(hwnd, GWL_EXSTYLE, intExTemp | WS_EX_TRANSPARENT | WS_EX_LAYERED);      SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_BORDER & ~WS_CAPTION);      currentX = 0;      currentY = 0;      SetWindowPos(hwnd, -1, currentX, currentY, Screen.currentResolution.width, Screen.currentResolution.height, SWP_SHOWWINDOW);      var margins = new MARGINS() { cxLeftWidth = -1 };      DwmExtendFrameIntoClientArea(hwnd, ref margins);   #endif    }}
[*]关注鼠标的位置和点击
将MyMouse.cs挂在一个GameObject上。
using System;using System.Collections;using System.Collections.Generic;using System.Runtime.InteropServices;using UnityEngine;public class MyMouse : MonoBehaviour{        public static extern short GetAsyncKeyState(int vKey);    private const int VK_LBUTTON = 0x01; //鼠标左键    private const int VK_RBUTTON = 0x02; //鼠标右键    private const int VK_MBUTTON = 0x04; //鼠标中键    private bool _isLeftDown;    private bool _isRightDown;    private bool _isMiddleDown;    public event Action<MouseKey, Vector3> MouseKeyDownEvent;    public event Action<MouseKey, Vector3> MouseKeyUpEvent;    public event Action<MouseKey, Vector3> MouseDragEvent;    public event Action<MouseKey> MouseKeyClickEvent;    public Vector3 MousePos{ get; private set; }    private bool _hasDragged;    private Vector3 _leftDownPos;    private Vector3 _rightDownPos;    private Vector3 _middleDownPos;    private void Start()    {      Init();    }    private void Update()   {      // 按下左键      if (GetAsyncKeyState(VK_LBUTTON) != 0)      {            if (!_isLeftDown)            {                _isLeftDown = true;                _leftDownPos = MouseKeyDown(MouseKey.Left);            }            else if (MousePos != Input.mousePosition)            {                MouseKeyDrag(MouseKey.Left);                if (!_hasDragged)                {                  _hasDragged = true;                }            }      }      // 按下右键      if (GetAsyncKeyState(VK_RBUTTON) != 0)      {            if (!_isRightDown)            {                _isRightDown = true;                _rightDownPos = MouseKeyDown(MouseKey.Right);            }            else if(MousePos != Input.mousePosition)            {                MouseKeyDrag(MouseKey.Right);                if (!_hasDragged)                {                  _hasDragged = true;                }            }      }      // 按下中键      if (GetAsyncKeyState(VK_MBUTTON) != 0)      {            if (!_isMiddleDown)            {                _isMiddleDown = true;                _middleDownPos = MouseKeyDown(MouseKey.Middle);            }            else if(MousePos != Input.mousePosition)            {                MouseKeyDrag(MouseKey.Middle);                if (!_hasDragged)                {                  _hasDragged = true;                }            }      }      // 抬起左键      if (GetAsyncKeyState(VK_LBUTTON) == 0 && _isLeftDown)      {            _isLeftDown = false;            MouseKeyUp(MouseKey.Left);            if (!_hasDragged && _leftDownPos == MousePos)            {                MouseKeyClick(MouseKey.Left);            }            _hasDragged = false;      }      // 抬起右键      if (GetAsyncKeyState(VK_RBUTTON) == 0 && _isRightDown)      {            _isRightDown = false;            MouseKeyUp(MouseKey.Right);            if (!_hasDragged && _rightDownPos == MousePos)            {                MouseKeyClick(MouseKey.Right);            }            _hasDragged = false;      }      // 抬起中键      if (GetAsyncKeyState(VK_MBUTTON) == 0 && _isMiddleDown)      {            _isMiddleDown = false;            MouseKeyUp(MouseKey.Middle);            if (!_hasDragged && _middleDownPos == MousePos)            {                MouseKeyClick(MouseKey.Middle);            }            _hasDragged = false;      }    }    private void OnDestroy()    {      Destroy();    }      public void Init()    {      _isLeftDown = false;      _isRightDown = false;      _isMiddleDown = false;      _hasDragged = false;    }      public void Destroy()    {            }    private Vector3 MouseKeyDown(MouseKey mouseKey)    {      RefreshMousePos();      MouseKeyDownEvent?.Invoke(mouseKey, MousePos);      // Log.Instance.ShowLog(string.Format("按下:" + mouseKey + ""+MousePos));      return MousePos;    }    private Vector3 MouseKeyUp(MouseKey mouseKey)    {      RefreshMousePos();      MouseKeyUpEvent?.Invoke(mouseKey, MousePos);      // Log.Instance.ShowLog(string.Format("抬起:" + mouseKey + "" + MousePos));      return MousePos;    }    private Vector3 MouseKeyDrag(MouseKey mouseKey)    {      RefreshMousePos();      MouseDragEvent?.Invoke(mouseKey, MousePos);      // Log.Instance.ShowLog(string.Format("拖动:" + mouseKey + "" + MousePos));      return MousePos;    }    private void MouseKeyClick(MouseKey mouseKey)    {      MouseKeyClickEvent?.Invoke(mouseKey);      // Log.Instance.ShowLog(string.Format("点击:" + mouseKey + "" + MousePos));    }    private Vector3 RefreshMousePos()    {      MousePos = Input.mousePosition;      return MousePos;    }    public Vector3 MousePosToWorldPos(Vector3 mousePos)    {      var screenInWorldPos = Camera.main.WorldToScreenPoint(mousePos);      var refPos = new Vector3(mousePos.x, mousePos.y, screenInWorldPos.z);      var pos = Camera.main.ScreenToWorldPoint(refPos);      return pos;    }}public enum MouseKey{   None,    Left,    Right,    Middle}
如何确认是否点击到桌宠?
关注鼠标Down事件,发生时,获得当前鼠标位置mousePos
var ray = Camera.main.ScreenPointToRay(mousePos); if (Physics.Raycast(ray, out RaycastHit hit)) {    // 判断hit的是否是桌宠。 }
页: [1]
查看完整版本: 使用Unity制作一个Windows桌面宠物