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

如何为UILineRenderer宽线条实现带容差的点击点位检测

Unity UGUI 宽线条点击检测实现

你原有函数仅支持判定点严格落在两点几何连线上,没有考虑线条渲染宽度,实际点击时只要手指/鼠标稍微偏一点就判定失败。宽线条判定的核心逻辑是:

  1. 计算点击点到线段的垂直距离,只要距离不超过线条半宽(可加少量交互缓冲)就算满足距离要求
  2. 确认点击点在线段上的投影落在线段两个端点的范围内,排除线段延长线区域的误判

修改后的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:54:25