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

VR游戏开发:锚点在Bounds内时如何获取边界最近点?

解决凹面网格内锚点获取Bounds边界最近点的问题

以下几种方法可以解决锚点处于Bounds内部时无法通过Collider.ClosestPointOnBounds获取边界最近点的问题:

  • 手动计算Bounds边界点
    利用Bounds的几何属性直接计算,不受锚点位置影响:

    public Vector3 GetClosestPointOnBounds(Collider collider, Vector3 anchorPoint)
    {
        Bounds bounds = collider.bounds;
        Vector3 offset = anchorPoint - bounds.center;
        
        // 将偏移量按Bounds的半尺寸归一化,并限制在[-1,1]范围内
        Vector3 normalizedOffset = new Vector3(
            Mathf.Clamp(offset.x / bounds.extents.x, -1f, 1f),
            Mathf.Clamp(offset.y / bounds.extents.y, -1f, 1f),
            Mathf.Clamp(offset.z / bounds.extents.z, -1f, 1f)
        );
        
        // 还原到Bounds边界上的点
        return bounds.center + Vector3.Scale(normalizedOffset, bounds.extents);
    }
    

    这个方法的核心是把锚点相对于Bounds中心的偏移,约束到Bounds的边界范围内,最终得到的点一定在Bounds的表面上,且是距离锚点最近的边界点。

  • 结合射线检测获取边界交点
    如果需要更精准的边界交点(比如针对非轴对齐的Bounds),可以从锚点向多个方向发射射线,找到与Bounds的第一个交点:

    public Vector3 GetClosestBoundaryPointViaRay(Collider collider, Vector3 anchorPoint)
    {
        Bounds bounds = collider.bounds;
        // 定义多个发射方向:正负xyz轴,以及四个对角线方向,确保覆盖所有可能的边界方向
        Vector3[] directions = new Vector3[] {
            Vector3.right, Vector3.left, Vector3.up, Vector3.down,
            Vector3.forward, Vector3.back,
            new Vector3(1,1,1).normalized, new Vector3(1,1,-1).normalized,
            new Vector3(1,-1,1).normalized, new Vector3(-1,1,1).normalized
        };
        
        float minDistance = float.MaxValue;
        Vector3 closestPoint = anchorPoint;
        
        foreach (var dir in directions)
        {
            if (Physics.Raycast(anchorPoint, dir, out RaycastHit hit, bounds.extents.magnitude * 2))
            {
                // 只保留与目标Collider的Bounds相关的交点
                if (hit.collider == collider && bounds.Contains(hit.point))
                {
                    float distance = Vector3.Distance(anchorPoint, hit.point);
                    if (distance < minDistance)
                    {
                        minDistance = distance;
                        closestPoint = hit.point;
                    }
                }
            }
        }
        
        // 如果没有检测到交点, fallback 到手动计算的方法
        return minDistance == float.MaxValue ? GetClosestPointOnBounds(collider, anchorPoint) : closestPoint;
    }
    

    这个方法适合处理旋转后的非轴对齐Bounds,不过性能略低于纯几何计算的方法,适合对精度要求较高的场景。

  • 若实际需求是避免网格碰撞,可改用Collider.ClosestPoint
    如果你最终的目的是让提示框避开网格碰撞,而非严格获取Bounds边界点,那么直接使用Collider.ClosestPoint(anchorPoint)会更合适——它会返回网格表面上距离锚点最近的点,沿该点与锚点的反方向放置提示框,能更精准地避开凹面网格的碰撞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:45:28