You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity2D实现鼠标悬停滑出按钮的问题求助(附代码)

解决UI按钮悬停滑动效果失效问题

问题根源

你用Physics2D.Raycast检测鼠标,但UI元素依赖Unity的EventSystem交互,而非2D物理碰撞体——除非给Canvas额外添加Physics2DRaycaster组件,否则物理射线无法识别UI。另外,OnMouseEnter/Exit只对带Collider2D的非UI物体生效,不适用于UI按钮。

正确实现方案

方案1:使用IPointerEnter/IPointerExit接口(推荐)

实现UI专属的事件接口,直接监听鼠标进入/离开状态,无需在Update里轮询:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SlideButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    public Button button;
    public float slideDownY = 205f;
    public float slideUpY = 295f;
    public float slideSpeed = 5f;

    private RectTransform rectTransform;
    private bool isHovering = false;

    private void Start()
    {
        rectTransform = GetComponent<RectTransform>();
        button.onClick.AddListener(OnButtonClick);
    }

    private void Update()
    {
        var targetY = isHovering ? slideDownY : slideUpY;
        rectTransform.anchoredPosition = Vector2.Lerp(
            rectTransform.anchoredPosition,
            new Vector2(rectTransform.anchoredPosition.x, targetY),
            slideSpeed * Time.deltaTime
        );
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        isHovering = true;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        isHovering = false;
    }

    void OnButtonClick()
    {
        // 后续添加点击逻辑
    }
}

方案2:使用EventTrigger组件(无需修改脚本结构)

  1. 在按钮GameObject上添加EventTrigger组件
  2. 点击Add New Event Type,分别添加Pointer Enter和Pointer Exit事件
  3. 将挂载SlideButton脚本的物体拖到事件对象槽,选择对应方法

修改后的脚本:

using UnityEngine;
using UnityEngine.UI;

public class SlideButton : MonoBehaviour
{
    public Button button;
    public float slideDownY = 205f;
    public float slideUpY = 295f;
    public float slideSpeed = 5f;

    private RectTransform rectTransform;
    private bool isHovering = false;

    private void Start()
    {
        rectTransform = GetComponent<RectTransform>();
        button.onClick.AddListener(OnButtonClick);
    }

    private void Update()
    {
        var targetY = isHovering ? slideDownY : slideUpY;
        rectTransform.anchoredPosition = Vector2.Lerp(
            rectTransform.anchoredPosition,
            new Vector2(rectTransform.anchoredPosition.x, targetY),
            slideSpeed * Time.deltaTime
        );
    }

    public void StartSlideDown()
    {
        isHovering = true;
    }

    public void StartSlideUp()
    {
        isHovering = false;
    }

    void OnButtonClick()
    {
        // 后续添加点击逻辑
    }
}

必要检查项

  • 场景中必须存在EventSystem(右键UI菜单可快速创建)
  • 按钮所在Canvas需保留默认的GraphicRaycaster组件
  • 脚本中rectTransform通过GetComponent自动获取,无需手动赋值
  • 确认按钮的Image组件Raycast Target选项处于勾选状态

内容的提问来源于stack exchange,提问作者Div

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:40:24