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
}

测试结果:

相关推荐
心前阳光3 小时前
Unity 模拟父子关系
android·unity·游戏引擎
在路上看风景6 小时前
26. Mipmap
unity
咸鱼永不翻身8 小时前
Unity视频资源压缩详解
unity·游戏引擎·音视频
在路上看风景8 小时前
4.2 OverDraw
unity
在路上看风景9 小时前
1.10 CDN缓存
unity
ellis197018 小时前
Unity插件SafeArea Helper适配异形屏详解
unity
nnsix19 小时前
Unity Physics.Raycast的 QueryTriggerInteraction枚举作用
unity·游戏引擎
地狱为王20 小时前
Cesium for Unity叠加行政区划线
unity·gis·cesium
小贺儿开发1 天前
Unity3D 八大菜系连连看
游戏·unity·互动·传统文化