PAYATHON 2026

Unity 中 OnMouseEnter() 与重叠 Collider 导致网格不显示

数据小陈

结论

问题可能与两层 collider 同时参与鼠标检测有关:外围 collider 用来判断鼠标是否进入网格,tile prefab 上的 collider 用来命中和高亮 tile。OnMouseEnter() 和 OnMouseExit() 针对具体 collider 触发,不能可靠地表示鼠标是否进入或离开整个网格。鼠标移到某个 tile 上时,命中的 collider 可能切换,因此外围对象的事件未必能准确反映网格区域的状态。

移除 tile 的 BoxCollider 后问题消失,说明可以重点检查 collider 的命中关系。不过,现有代码和描述不足以确定异常具体由哪个 collider、碰撞层或摄像机设置导致。

建议的处理方式

分别检测鼠标是否位于网格内,以及鼠标命中了哪个 tile:

  1. 用外围区域 collider 判断鼠标是否在网格范围内,并据此显示或隐藏网格。
  2. 鼠标位于网格内时,通过 raycast 或点检测查询 tile collider,单独更新高亮 tile。
  3. 鼠标离开外围区域时,清除当前高亮并隐藏网格。

这样,tile collider 用于选中 tile,外围区域检测用于控制网格显示状态。

如果项目使用 2D collider,可以每帧取得鼠标的世界坐标,再分别检测外围区域和 tile:

Vector3 mouseWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 mousePoint = new Vector2(mouseWorld.x, mouseWorld.y);

bool insideGrid = gridArea.OverlapPoint(mousePoint);
if (!insideGrid)
{
    HideGrid();
    SetHighlightedTile(null);
    return;
}

ShowGrid();
Collider2D tileHit = Physics2D.OverlapPoint(mousePoint, tileLayer);
SetHighlightedTile(tileHit);

这里的 gridArea 是外围的 Collider2D。tileLayer 应只包含 tile 所在的 layer,以免外围 collider 被当作 tile 命中。ShowGrid()、HideGrid() 和 SetHighlightedTile() 需要根据项目现有逻辑实现。示例假设网格位于 XY 平面并使用 2D collider;如果项目使用 3D BoxCollider,应改用 Collider.Raycast 或 Physics.Raycast,不要混用 2D 和 3D 物理查询。

保留 OnMouse 事件时

外围对象的 OnMouseEnter() 和 OnMouseExit() 也可以继续控制网格显示。需要确认 tile collider 不会让外围对象的事件状态偏离预期。tile 的高亮由 tile 自己的命中检测处理;鼠标移出网格时,记得清除高亮。实际行为还受 collider 类型、对象层级、摄像机和物理设置影响,可以分别检查问题 tile 和正常 tile 命中了哪个 collider。

快速移动时出现的白色闪烁,可能是高亮逻辑切换新旧 tile 时,先恢复了默认颜色,再设置透明度。更新高亮时,先取消上一个 tile 的高亮,再设置新 tile 的颜色;没有命中 tile 时,也要显式恢复或清除状态。

备注:内容仅供参考。