PointerEnter、PointerExit、PointerDown、PointerUp——鼠标点击物体,则开始旋转,鼠标离开或者松开物体,则停止旋转

〇、需求来源

  • 需求:鼠标点击手轮,则开始旋转(左键顺时针转,右键逆时针转),鼠标离开手轮或者鼠标松开手轮,则停止旋转。

  • 实现思路:

    • (1)这是一个手动轮,鼠标悬停在该物体上的时候,按下鼠标左键,它顺时针旋转,如果按下鼠标右键,它逆时针旋转。在轮子旋转的时候,即便鼠标没弹起,失去焦点,它也会停止旋转。
    • (2)也就是说:
      鼠标左键长按它------>顺时针转
      鼠标右键长按它------>逆时针转
      一旦松开鼠标,则手轮停止旋转。
      另外,即便没松开鼠标,如果鼠标离开手轮,手轮也停止旋转。
    • (3)一句话总结:鼠标点击手轮,则开始旋转,鼠标离开手轮或者鼠标松开手轮,则停止旋转。
  • 入口和出口事件:

    • (1)旋转入口:手轮被点击
    • (2)停止旋转的条件(出口):退出悬停 or 松开物体

一、对比这两组Pointer事件

事件类型 中文释义 核心逻辑
PointerDown 按下物体 逻辑起点:鼠标在物体碰撞体范围内按下。此时该物体会"捕获"指针,后续动作将与此物体绑定。
PointerUp 松开物体 逻辑终点 :此前按下的按键被松开。注意: 无论此时鼠标是否还在物体上方,事件都会发送给最初按下的那个物体。
PointerEnter 进入物体 视觉反馈:鼠标光标移动到物体碰撞体上方。
PointerExit 离开物体 视觉反馈:鼠标光标离开物体碰撞体范围。

二、PointerUp事件说明

它并不是单纯的【鼠标弹起】或者【鼠标松开】。

这个事件要发生,必须是前面发生过PointerDown事件,也就是说它俩是配对的。

鼠标在其它区域被按下,然后再移动到这个物体上弹起,也不会发生PointerUp事件。

三、PointerDown发生的时候,如何获取是左键还是右键

csharp 复制代码
//鼠标点击物体:左键 | 右键
leftWheel.OnEventTriggerAddListener(EventTriggerType.PointerDown, (data) =>
{
    if(data.button == PointerEventData.InputButton.Left)         //左键点了手轮物体
    {
        Debug.Log("【鼠标左键】点了【左边手轮】");
    }
    else if(data.button == PointerEventData.InputButton.Right)   //右键点了手轮物体
    {
        Debug.Log("【鼠标右键】点了【左边手轮】");
    }
});
csharp 复制代码
/// <summary>
/// 给一个GameObject添加一个EventTrigger的事件侦听,绑定一个Action方法,Action捕获PointerEventData
/// </summary>
/// <param name="obj"></param>
/// <param name="eventType"></param>
/// <param name="fn"></param>
public static void OnEventTriggerAddListener(this GameObject obj, EventTriggerType eventType, Action<PointerEventData> fn)
{
    Action<PointerEventData> unityAction = (data) => {fn(data); };

    //EventTrigger组件判空
    EventTrigger trigger = obj.GetComponent<EventTrigger>();
    if (!trigger)
    {
        trigger = obj.AddComponent<EventTrigger>();
    }

    //碰撞体判空     
    if (!obj.GetComponent<Collider>())
    {
        obj.AddComponent<MeshCollider>();
        Debug.LogWarning($"{obj}自动添加MeshCollider组件");
    }

    //添加侦听
    EventTrigger.Entry entry = new EventTrigger.Entry();
    entry.eventID = eventType;
    entry.callback.AddListener(data => unityAction.Invoke((PointerEventData)data));
    trigger.triggers.Add(entry);
}

四、测试脚本

csharp 复制代码
	/// <summary>
	/// 左手轮
	/// </summary>
	[SerializeField]
	[Header("左手轮")]
	public GameObject leftWheel;
	
    /// <summary>
    /// 鼠标是否悬停在左手轮上
    /// </summary>
    private bool isHoverLeft = false;

在Start里面绑定代码

csharp 复制代码
void Start()
{
    #region=====================脚本绑定=======================begin
    //光标【进入】【左边手轮】------光标悬停
    leftWheel.OnEventTriggerAddListener(EventTriggerType.PointerEnter, () =>
    {
        isHoverLeft = true;
        Debug.Log("【左边手轮】得着焦点");
    });

    //光标【退出】【左边手轮】------光标退出悬停
    leftWheel.OnEventTriggerAddListener(EventTriggerType.PointerExit, () =>
    {
        isHoverLeft = false;
        Debug.Log("【左边手轮】失去焦点");
    });

    //鼠标点击物体:左键 | 右键
    leftWheel.OnEventTriggerAddListener(EventTriggerType.PointerDown, (data) =>
    {
        if(data.button == PointerEventData.InputButton.Left)         //左键点了手轮物体
        {
            Debug.Log("【鼠标左键】点了【左边手轮】");
        }
        else if(data.button == PointerEventData.InputButton.Right)   //右键点了手轮物体
        {
            Debug.Log("【鼠标右键】点了【左边手轮】");
        }
    });

    //鼠标松开物体:鼠标弹起
    leftWheel.OnEventTriggerAddListener(EventTriggerType.PointerUp, (data) =>
    {           
        if (isHoverLeft) 
        {
            if (data.button == PointerEventData.InputButton.Left)         //左键点了手轮
            {
                Debug.Log("【鼠标左键】从【左边手轮】上弹起");
            }
            else if (data.button == PointerEventData.InputButton.Right)   //右键点了手轮
            {
                Debug.Log("【鼠标右键】从【左边手轮】上弹起");
            }
        }
        else
        {
            if (data.button == PointerEventData.InputButton.Left)         //左键点了手轮
            {
                Debug.Log("【鼠标左键】在【其它地方】弹起");
            }
            else if (data.button == PointerEventData.InputButton.Right)   //右键点了手轮
            {
                Debug.Log("【鼠标右键】在【其它地方】弹起");
            }
        }            
    });

    #endregion =================脚本绑定=======================end
}

测试结果:

相关推荐
玄米乌龙茶1232 小时前
LLM成长笔记(十三):系统设计与项目实战
笔记·unity·游戏引擎
_Evan_Yao9 小时前
游戏和编程两不误:用Unity做一个简单小游戏
后端·游戏·unity·游戏引擎
冰凌糕10 小时前
Unity3D Shader 渲染状态详解
unity
郝学胜-神的一滴11 小时前
[简化版 GAMES 101] 计算机图形学 10:反走样与深度缓冲核心解析
c++·unity·godot·图形渲染·three.js·unreal engine·opengl
技术探讨者1 天前
极境导表工具 —— 让配置数据成为游戏开发的效率引擎
unity·编辑器·ai编程·游戏策划
游乐码1 天前
Unity基础(六)小案例
游戏·unity·游戏引擎
Sator11 天前
Unity2022版接入MCP
unity·ai编程
mxwin2 天前
Unity Shader URP 使用模板测试 · 深度测试实现秘境空间效果
unity·游戏引擎·shader
真鬼1233 天前
【Unity 6】Unity6快捷下载,快速下载
unity·游戏引擎
会潜水的小火龙3 天前
unity打包apk报错Failure to initialize问题解决方法
unity·游戏引擎