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

-
实现思路:
- (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
}
测试结果:
