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

孙广东  2015.11.8

这篇文章是 无意间 从网上的 看到的一篇文章, 个人角色挺有意思的。  当然了原理还是很简单的。

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

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

2、只针对pc项目。


一、导入包

using System.Runtime.InteropServices;

using System;


二、光标资源加载函数

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


三、设置系统指针函数

        //设置系统指针函数(用hcur替换id定义的光标)
        //hcur用于表示指针或句柄的特定类型,可以用LoadCursorFromFile函数加载一个路径下的.cur指针文件
        //id是系统光标标识符,例:
        //* OCR_APPSTARTING:标准箭头和小的沙漏;
        //* OCR_NORAAC:标准箭头;
        //* OCR_CROSS:交叉十字线光标;
        //* OCR_HAND:手的形状(WindowsNT5.0和以后版本);
        //* OCR_HELP:箭头和向东标记;
        //* OCR_IBEAM:I形梁;
        //* OCR_NO:斜的圆;
        //* OCR_SIZEALL:四个方位的箭头分别指向北、南、东、西;
        //* OCR_SIZENESEW:双箭头分别指向东北和西南;
        //* OCR_SIZENS:双箭头,分别指向北和南;
        //* OCR_SIZENWSE:双箭头分别指向西北和东南;
        //* OCR_SIZEWE:双箭头分别指向西和东;

        [DllImport("User32.DLL")]
        public static extern bool SetSystemCursor(IntPtr hcur, uint id);
        public const uint OCR_NORMAL = 32512;


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

        //查询或设置的系统级参数函数
        //* uiAction该参数指定要查询或设置的系统级参数,SPI_SETCURSORS:重置系统光标
        //* fWinIni该参数指定在更新用户配置文件之后广播SPI_SENDWININICHANGE消息
        

        [DllImport("User32.DLL")]
        public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);
        public const uint SPI_SETCURSORS = 87;
        public const uint SPIF_SENDWININICHANGE = 2;


五、设置或恢复

        //设置系统自带图标
        //* SetSystemCursor(Cursors.WaitCursor.CopyHandle(), OCR_NORMAL);
        
        //设置外部图标文件
        //* SetSystemCursor(hcur_normal, OCR_NORMAL);
        
        public string path;

        void Start()
        {
            path = UnityEngine.Application.dataPath;
        }

        void Update()   // 如果是在 FixedUpdate 内检测 会出现漏检的问题!
        {
            if (Input.GetMouseButtonDown(0))
            {
                //鼠标点击图标
                IntPtr hcur_click = LoadCursorFromFile(path + "/03.cur");
                SetSystemCursor(hcur_click, OCR_NORMAL);
            }

            if (Input.GetMouseButtonUp(0))
            {
                //正常状态图标
                IntPtr hcur_normal = LoadCursorFromFile(path + "/01.cur");
                SetSystemCursor(hcur_normal, OCR_NORMAL);
            }
        }

        void OnApplicationQuit()
        {
            //恢复为系统默认图标
            SystemParametersInfo(SPI_SETCURSORS, 0, IntPtr.Zero, SPIF_SENDWININICHANGE);
        }


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

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


Unity编辑器定制:更改系统默认鼠标图标_第1张图片




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

using System;
using UnityEngine;
using UnityEditor;
using System.IO;

using System.Runtime.InteropServices;

namespace DajiaGame.Px
{
    /// 
    /// 描述:自动保存项目资源到磁盘(因为不到磁盘git的提交不是最新的数据)
    /// 1、与 File/Save Project 菜单的区别是 增加快捷键 自动保存
    /// 2、添加启动VS 的菜单
    /// 3、更改系统鼠标图案
    /// author: 孙广东
    /// 
    [InitializeOnLoad]
    public class AutoSaveProject : Editor
    {
        #region ===字段===

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

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

        //设置系统自带图标
        //* SetSystemCursor(Cursors.WaitCursor.CopyHandle(), OCR_NORMAL);

        //设置外部图标文件
        //* SetSystemCursor(hcur_normal, OCR_NORMAL);

        public static string path;

#endregion  // ========================================================================================


        private static float spanTime = 50f;
        private static float deltaTime = 0f;

        #endregion

        #region ===属性===
        #endregion

        static AutoSaveProject()    // 构造函数
        {
            EditorApplication.update += Update;
            EditorApplication.playmodeStateChanged += PlaymodeStateChanged;

            path = Application.dataPath + "/Editor/Resources/Cursor";
        }

        static void PlaymodeStateChanged()
        {
            if (EditorApplication.isPaused && CombatView.Instance != null)
            {
                string path = Application.dataPath + "/CombatEventLog.txt";
                if (File.Exists(path))
                {
                    System.Diagnostics.Process.Start("notepad.exe", path);
                }
            }

            if (!Application.isPlaying)
            {
                //恢复为系统默认图标
                SystemParametersInfo(SPI_SETCURSORS, 0, IntPtr.Zero, SPIF_SENDWININICHANGE);
            }
        }

        static void Update()  // 如果是在 FixedUpdate 内检测 会出现漏检的问题!
        {
            // 【 自动保存
            //deltaTime += Time.fixedDeltaTime;
            //if (deltaTime > spanTime)
            //{
            //    deltaTime = 0f;
            //    AutoSave2();
            //    // MustExtensions.MustBeFalse(true, "自动保存了项目");
            //}

            // 【更改系统鼠标 Icon
            if (Input.GetMouseButtonDown(0))
            {
                //鼠标点击图标
                IntPtr hcur_click = LoadCursorFromFile(path + "/down.cur");   // "/down.ani");
                SetSystemCursor(hcur_click, OCR_NORMAL);
            }

            if (Input.GetMouseButtonUp(0))
            {
                //正常状态图标
                IntPtr hcur_normal = LoadCursorFromFile(path + "/normal.ani"); // "/normal.cur");
                SetSystemCursor(hcur_normal, OCR_NORMAL);
            }
        }

        #region ===方法===

        // 【1 通过执行 SaveProject 菜单 (失败!)
        //[MenuItem("File/Save Project1 %#&1")]
        //private static void AutoSave1()
        //{
        //    EditorApplication.ExecuteMenuItem("File/Save Project");    // 这个菜单特殊不可以!
        //}

        // 【2 通过API保存
        [MenuItem("File/Save Project2 %#&2")]
        private static void AutoSave2()
        {
            EditorApplication.SaveAssets();
        }

        // 【3 通过API保存
        [MenuItem("Visual Studio Unity/Open VS Project")]
        private static void VisualStudioProject()
        {
            EditorApplication.ExecuteMenuItem("Assets/Open C# Project");    // 这个菜单特殊不可以!
        }

        #endregion
    }
}





你可能感兴趣的:(unity3d,Editor私人定制)