Unity编辑器定制:更改系统默认鼠标图标

发表于2017-10-12
评论0 2.6k浏览

Unity编辑器可以定制就可以实现多种多样的功能,这里和大家介绍下如何更改系统默认鼠标图标,要想知道更改的方法,就必须知道更改系统默认鼠标图标的原理,当然原理还是很简单的,一起看看吧。


直接用windows API改系统图标的方式,不过这种方式的劣点有2个:

1、直接更改系统的鼠标图标,不只是针对某一个窗口,所以在程序退出时需要还原默认图标,不然鼠标一直是保持我们更改后的效果;

2、只针对pc项目。


一、导入包

  1. using System.Runtime.InteropServices;  
  2.   
  3. using System;  


二、光标资源加载函数

  1. //光标资源加载函数  
  2. //fileName为加载路径下的.cur文件  
  3. [DllImport("User32.DLL")]  
  4. public static extern IntPtr LoadCursorFromFile(string fileName);  


三、设置系统指针函数

  1. //设置系统指针函数(用hcur替换id定义的光标)  
  2. //hcur用于表示指针或句柄的特定类型,可以用LoadCursorFromFile函数加载一个路径下的.cur指针文件  
  3. //id是系统光标标识符,例:  
  4. //* OCR_APPSTARTING:标准箭头和小的沙漏;  
  5. //* OCR_NORAAC:标准箭头;  
  6. //* OCR_CROSS:交叉十字线光标;  
  7. //* OCR_HAND:手的形状(WindowsNT5.0和以后版本);  
  8. //* OCR_HELP:箭头和向东标记;  
  9. //* OCR_IBEAM:I形梁;  
  10. //* OCR_NO:斜的圆;  
  11. //* OCR_SIZEALL:四个方位的箭头分别指向北、南、东、西;  
  12. //* OCR_SIZENESEW:双箭头分别指向东北和西南;  
  13. //* OCR_SIZENS:双箭头,分别指向北和南;  
  14. //* OCR_SIZENWSE:双箭头分别指向西北和东南;  
  15. //* OCR_SIZEWE:双箭头分别指向西和东;  
  16.   
  17. [DllImport("User32.DLL")]  
  18. public static extern bool SetSystemCursor(IntPtr hcur, uint id);  
  19. public const uint OCR_NORMAL = 32512;  


四、查询或设置的系统级参数函数(用于重置系统光标)

  1. //查询或设置的系统级参数函数  
  2. //* uiAction该参数指定要查询或设置的系统级参数,SPI_SETCURSORS:重置系统光标  
  3. //* fWinIni该参数指定在更新用户配置文件之后广播SPI_SENDWININICHANGE消息  
  4.   
  5.   
  6. [DllImport("User32.DLL")]  
  7. public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);  
  8. public const uint SPI_SETCURSORS = 87;  
  9. public const uint SPIF_SENDWININICHANGE = 2;  


五、设置或恢复

  1. //设置系统自带图标  
  2. //* SetSystemCursor(Cursors.WaitCursor.CopyHandle(), OCR_NORMAL);  
  3.   
  4. //设置外部图标文件  
  5. //* SetSystemCursor(hcur_normal, OCR_NORMAL);  
  6.   
  7. public string path;  
  8.   
  9. void Start()  
  10. {  
  11.     path = UnityEngine.Application.dataPath;  
  12. }  
  13.   
  14. void Update()   // 如果是在 FixedUpdate 内检测 会出现漏检的问题!  
  15. {  
  16.     if (Input.GetMouseButtonDown(0))  
  17.     {  
  18.         //鼠标点击图标  
  19.         IntPtr hcur_click = LoadCursorFromFile(path   "/03.cur");  
  20.         SetSystemCursor(hcur_click, OCR_NORMAL);  
  21.     }  
  22.   
  23.     if (Input.GetMouseButtonUp(0))  
  24.     {  
  25.         //正常状态图标  
  26.         IntPtr hcur_normal = LoadCursorFromFile(path   "/01.cur");  
  27.         SetSystemCursor(hcur_normal, OCR_NORMAL);  
  28.     }  
  29. }  
  30.   
  31. void OnApplicationQuit()  
  32. {  
  33.     //恢复为系统默认图标  
  34.     SystemParametersInfo(SPI_SETCURSORS, 0, IntPtr.Zero, SPIF_SENDWININICHANGE);  
  35. }  


六、将这个脚本挂在场景任意物体(全局不会销毁或隐藏的)上就可以了,再把你想替换的鼠标.cur文件click.cur和normal.cur(名字自定义)放在Assets同级目录下,好了本篇unity3d教程到此结束,下篇我们再会!

由于鼠标光标的截图 无法被捕捉到, 所以看不到效果图了!






如果   只希望在 UnityEditor 下显示的话, 可以这样:

  1. using System;  
  2. using UnityEngine;  
  3. using UnityEditor;  
  4. using System.IO;  
  5.   
  6. using System.Runtime.InteropServices;  
  7.   
  8. namespace DajiaGame.Px  
  9. {  
  10.     /// <summary>  
  11.     /// 描述:自动保存项目资源到磁盘(因为不到磁盘git的提交不是最新的数据)  
  12.     /// 1、与 File/Save Project 菜单的区别是 增加快捷键 自动保存  
  13.     /// 2、添加启动VS 的菜单  
  14.     /// 3、更改系统鼠标图案  
  15.     /// author: 孙广东  
  16.     /// </summary>  
  17.     [InitializeOnLoad]  
  18.     public class AutoSaveProject : Editor  
  19.     {  
  20.         #region ===字段===  
  21.  
  22. #region // ========================================================================================  
  23.         //光标资源加载函数  
  24.         //fileName为加载路径下的.cur文件  
  25.         [DllImport("User32.DLL")]  
  26.         public static extern IntPtr LoadCursorFromFile(string fileName);  
  27.         //设置系统指针函数(用hcur替换id定义的光标)  
  28.         //hcur用于表示指针或句柄的特定类型,可以用LoadCursorFromFile函数加载一个路径下的.cur指针文件  
  29.         //id是系统光标标识符,例:  
  30.         //* OCR_APPSTARTING:标准箭头和小的沙漏;  
  31.         //* OCR_NORAAC:标准箭头;  
  32.         //* OCR_CROSS:交叉十字线光标;  
  33.         //* OCR_HAND:手的形状(WindowsNT5.0和以后版本);  
  34.         //* OCR_HELP:箭头和向东标记;  
  35.         //* OCR_IBEAM:I形梁;  
  36.         //* OCR_NO:斜的圆;  
  37.         //* OCR_SIZEALL:四个方位的箭头分别指向北、南、东、西;  
  38.         //* OCR_SIZENESEW:双箭头分别指向东北和西南;  
  39.         //* OCR_SIZENS:双箭头,分别指向北和南;  
  40.         //* OCR_SIZENWSE:双箭头分别指向西北和东南;  
  41.         //* OCR_SIZEWE:双箭头分别指向西和东;  
  42.         [DllImport("User32.DLL")]  
  43.         public static extern bool SetSystemCursor(IntPtr hcur, uint id);  
  44.         public const uint OCR_NORMAL = 32512;  
  45.   
  46.         //查询或设置的系统级参数函数  
  47.         //* uiAction该参数指定要查询或设置的系统级参数,SPI_SETCURSORS:重置系统光标  
  48.         //* fWinIni该参数指定在更新用户配置文件之后广播SPI_SENDWININICHANGE消息  
  49.         [DllImport("User32.DLL")]  
  50.         public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);  
  51.         public const uint SPI_SETCURSORS = 87;  
  52.         public const uint SPIF_SENDWININICHANGE = 2;  
  53.   
  54.         //设置系统自带图标  
  55.         //* SetSystemCursor(Cursors.WaitCursor.CopyHandle(), OCR_NORMAL);  
  56.   
  57.         //设置外部图标文件  
  58.         //* SetSystemCursor(hcur_normal, OCR_NORMAL);  
  59.   
  60.         public static string path;  
  61.  
  62. #endregion  // ========================================================================================  
  63.   
  64.   
  65.         private static float spanTime = 50f;  
  66.         private static float deltaTime = 0f;  
  67.  
  68.         #endregion  
  69.  
  70.         #region ===属性===  
  71.         #endregion  
  72.   
  73.         static AutoSaveProject()    // 构造函数  
  74.         {  
  75.             EditorApplication.update  = Update;  
  76.             EditorApplication.playmodeStateChanged  = PlaymodeStateChanged;  
  77.   
  78.             path = Application.dataPath   "/Editor/Resources/Cursor";  
  79.         }  
  80.   
  81.         static void PlaymodeStateChanged()  
  82.         {  
  83.             if (EditorApplication.isPaused && CombatView.Instance != null)  
  84.             {  
  85.                 string path = Application.dataPath   "/CombatEventLog.txt";  
  86.                 if (File.Exists(path))  
  87.                 {  
  88.                     System.Diagnostics.Process.Start("notepad.exe", path);  
  89.                 }  
  90.             }  
  91.   
  92.             if (!Application.isPlaying)  
  93.             {  
  94.                 //恢复为系统默认图标  
  95.                 SystemParametersInfo(SPI_SETCURSORS, 0, IntPtr.Zero, SPIF_SENDWININICHANGE);  
  96.             }  
  97.         }  
  98.   
  99.         static void Update()  // 如果是在 FixedUpdate 内检测 会出现漏检的问题!  
  100.         {  
  101.             // 【 自动保存  
  102.             //deltaTime  = Time.fixedDeltaTime;  
  103.             //if (deltaTime > spanTime)  
  104.             //{  
  105.             //    deltaTime = 0f;  
  106.             //    AutoSave2();  
  107.             //    // MustExtensions.MustBeFalse(true, "自动保存了项目");  
  108.             //}  
  109.   
  110.             // 【更改系统鼠标 Icon  
  111.             if (Input.GetMouseButtonDown(0))  
  112.             {  
  113.                 //鼠标点击图标  
  114.                 IntPtr hcur_click = LoadCursorFromFile(path   "/down.cur");   // "/down.ani");  
  115.                 SetSystemCursor(hcur_click, OCR_NORMAL);  
  116.             }  
  117.   
  118.             if (Input.GetMouseButtonUp(0))  
  119.             {  
  120.                 //正常状态图标  
  121.                 IntPtr hcur_normal = LoadCursorFromFile(path   "/normal.ani"); // "/normal.cur");  
  122.                 SetSystemCursor(hcur_normal, OCR_NORMAL);  
  123.             }  
  124.         }  
  125.  
  126.         #region ===方法===  
  127.   
  128.         // 【1 通过执行 SaveProject 菜单 (失败!)  
  129.         //[MenuItem("File/Save Project1 %#&1")]  
  130.         //private static void AutoSave1()  
  131.         //{  
  132.         //    EditorApplication.ExecuteMenuItem("File/Save Project");    // 这个菜单特殊不可以!  
  133.         //}  
  134.   
  135.         // 【2 通过API保存  
  136.         [MenuItem("File/Save Project2 %#&2")]  
  137.         private static void AutoSave2()  
  138.         {  
  139.             EditorApplication.SaveAssets();  
  140.         }  
  141.   
  142.         // 【3 通过API保存  
  143.         [MenuItem("Visual Studio Unity/Open VS Project")]  
  144.         private static void VisualStudioProject()  
  145.         {  
  146.             EditorApplication.ExecuteMenuItem("Assets/Open C# Project");    // 这个菜单特殊不可以!  
  147.         }  
  148.  
  149.         #endregion  
  150.     }  
  151. }  

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论