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
}

测试结果:

相关推荐
wy3258643646 小时前
Unity 新输入系统InputSystem(基本操作)
unity·c#·游戏引擎
WarPigs6 小时前
着色器multi_compile笔记
unity·着色器
ECHO飞跃 0126 小时前
Unity2019 本地推理 通义千问0.5-1.5B微调导入
人工智能·深度学习·unity·llama
Unity游戏资源学习屋6 小时前
【Unity UI资源包】GUI Pro - Casual Game 专为休闲手游打造的专业级UI资源包
ui·unity
冰凌糕7 小时前
Unity3D Shader 顶点法线外扩实现描边效果
unity
小菱形_8 小时前
【Unity】TimeLine
unity·游戏引擎
小贺儿开发1 天前
Unity3D 自动化物流分拣模拟
运维·科技·unity·自动化·人机交互·传送带·物流分拣
EQ-雪梨蛋花汤1 天前
【3D可视化】基于 Unity 的智慧体育馆三维信息可视化大屏实践
3d·unity·信息可视化
weixin_424294671 天前
Unity 使用Steamworks.NET
unity·游戏引擎
ellis19701 天前
Unity资源管理框架Addressables总结
unity·游戏引擎