Unity3D UGUI鼠标光标变换

UGUI实现动态光标样式


想要实现鼠标移到可交互的UGUI上时由箭头变为小手,查了一些资料发现旧版的 OnMouseEnter() OnMouseExit() 函数不是特别好用,首先新版本的UGUI没有自带 Collider 或者 RigidBody ,导致上述两个函数无法监测到对应事件;其次就是由于我开发的项目使用了多摄像头,就算给对应 UGUI 加上了碰撞器或者刚体也没办法正常监测到鼠标的事件。

所以我结合网上资料发现在 UGUI 系统上,EventSystem 提供了一些方法。那就是 EventSystem.current.IsPointerOverGameObject() 方法,作用:判断鼠标是否点击在UI上。 然后再利用 Cursor.SetCursor() 函数和 Resources.Load() 函数对光标改变进行设置。

下面一步步说。

检测鼠标是否悬停在UGUI上


if (EventSystem.current.IsPointerOverGameObject())
{
    //变换光标
}

检测非常简单,一步到位,但现在还存在一个问题,就是不仅鼠标停留在按钮上时 EventSystem.current.IsPointerOverGameObject() 返回 true , canvas 里的所有对象包括各种 Image、TextMeshPro 都会返回 true 值。

但EventSystem貌似早就为我们想好了。在各个 UGUI 组件上的有一个 Raycast Type 的复选框,只要我们把勾选去掉即可。

因此我推测 EventSystem.current.IsPointerOverGameObject() 方法的原理是,是根据UI上的 Raycast Target 的勾选来遍历,哪些UGUI需要判断,哪些不需要。

改变鼠标光标


光标应该图片是经过处理的 png ,沿着边框用 photoshop 抠成透明。将处理好的 png 导入 Unity3D ,可以在 EventSystem 上挂载如下的脚本 CursorChange.cs

using UnityEngine;
using System.Collections;
 
public class CursorChange : MonoBehaviour
{
    [serializefield] private Texture2D cursorTexture;
    void Start()
    {
        Cursor.SetCursor(cursorTexture, Vector2.zero, CursorMode.Auto);
    }
}

将导入的png设置为下图

然后把png拖到上述代码留出的 cursorTexture,点击运行即可看到光标替成了

这里脚本就一行,就要是3个参数,第1个参数cursorTexture大家已经知道是什么了,第2个参数Vector2.zero,也就是二维坐标(0,0)是指取材质图片a.png的左上角作为点击点,第3个参数CursorMode.Auto是指渲染形式,Audo为平台自适应显示,支持此样式则显示,不支持不显示。ForceSoftware强制平台显示此样式。

综合实现


结合上述两个点,实现动态改变光标的代码如下:

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class CursorChange : MonoBehaviour
{
    private Texture2D cursorTexture;
    private bool IsPointerOver;
    void Start()
    {
        cursorTexture = Resources.Load("CursorImage") as Texture2D;
        Cursor.SetCursor(null, new Vector2(43f, 0f), CursorMode.Auto);
        IsPointerOver = false;
        //Cursor.SetCursor(cursorTexture, new Vector2(43f, 0f), CursorMode.Auto);
    }
    private void Update()
    {
        if (EventSystem.current.IsPointerOverGameObject())
            OnMouseEnter();
        else
            OnMouseExit();
    }
    private void OnMouseEnter()
    {
        if (!IsPointerOver)
        {
            Cursor.SetCursor(cursorTexture, new Vector2(43f, 0f), CursorMode.Auto);
            IsPointerOver = true;
            //Debug.Log("bark");
        }
    }
    void OnMouseExit()
    {
        if (IsPointerOver)
        {
            Cursor.SetCursor(null, new Vector2(43f, 0f), CursorMode.Auto);
            IsPointerOver = false;
            //Debug.Log("Gou Jiao");
        }
    }
}

Resources.Load() 语句从 Resourses 文件夹中的对应路径加载资源文件或者对象,可以降低代码耦合度。使用这个方法要修改 ResoursespngTexture TypeCursor

重写的 OnMouseEnter() OnMouseExit() 实际上是利用 Update() EventSystem.current.IsPointerOverGameObject() 的实时检测来判断进出鼠标进出 UGUI

参考文献


Unity UGUI鼠标点击UI不受影响方法IsPointerOverGameObject

【Unity3D】改变鼠标样式

Unity:资源加载Resources.Load

Invalid texture used for cursor - check importer settings or texture creation. Texture must be RGBA3

unity鼠标光标样式改变

posted on 2022-04-22 11:17  lylygoing  阅读(1278)  评论(0编辑  收藏  举报

导航