如何为UILineRenderer宽线条实现带容差的点击点位检测
Unity UGUI 宽线条点击检测实现
你原有函数仅支持判定点严格落在两点几何连线上,没有考虑线条渲染宽度,实际点击时只要手指/鼠标稍微偏一点就判定失败。宽线条判定的核心逻辑是:
- 计算点击点到线段的垂直距离,只要距离不超过线条半宽(可加少量交互缓冲)就算满足距离要求
- 确认点击点在线段上的投影落在线段两个端点的范围内,排除线段延长线区域的误判
修改后的代码
public bool PointIsOnLine(Vector2 currPoint, UILineRenderer line) { Vector2 point1 = line.points[0]; Vector2 point2 = line.points[1]; Vector2 lineVec = point2 - point1; Vector2 pointVec = currPoint - point1; // 计算线段长度平方,处理两点重合的边界情况 float lineSqrLen = lineVec.sqrMagnitude; float hitTolerance = line.thickness / 2f + 2f; // 额外加2像素点击缓冲,可按需调整 if (lineSqrLen < 0.001f) { // 线条退化为点时,直接判断距离 return pointVec.sqrMagnitude <= hitTolerance * hitTolerance; } // 计算叉乘,得到点到直线的垂直距离相关值 float cross = pointVec.x * lineVec.y - pointVec.y * lineVec.x; // 垂直距离 = |cross| / 线段长度,和容差比较时两边同乘线段长度避免开方,提升性能 if (Mathf.Abs(cross) > hitTolerance * Mathf.Sqrt(lineSqrLen)) return false; // 计算点在线段上的投影位置,判断是否落在两个端点范围内 float dot = Vector2.Dot(pointVec, lineVec); if (dot < 0) return false; // 投影在p1外侧 if (dot > lineSqrLen) return false; // 投影在p2外侧 return true; }
实现说明
- 距离判断时用了代数变形避免开方运算,比直接计算距离性能更好,判定结果完全一致
- 判定阈值在半线宽基础上额外加了2像素缓冲,适配移动端手指点击的交互场景,不需要可以直接删除
- 如果你的
UILineRenderer开启了圆角端点,可以在现有逻辑基础上补充判定:当点投影在线段端点外时,额外判断点到对应端点的距离是否小于等于半线宽,就能完整覆盖圆角的点击区域
内容的提问来源于stack exchange,提问作者Majellan
相关产品推荐
相关产品推荐

