Unity3d Select Object 离点击最近没有碰撞器

Unity3d Select Object nearest to click no colliders

我有一个用于开发的 Mixamo 模型。该模型完全装配有骨架。我正在尝试创建一个函数,允许我在没有对撞机的情况下 select 一块骨架。

此当前脚本仅适用于对撞机,

public void RegisterSelectControls()
{
    if (Input.GetMouseButtonDown(0))
    {
        var hit = new RaycastHit();
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out hit, 100.0f))
        {
            var objectHitName = hit.collider.transform.name;
            Debug.Log(objectHitName);
        }
    }
}

有没有办法检测骨骼的哪一部分被点击,或者骨骼的最接近点击的部分?

我不想手动将碰撞器添加到每个 body 部分,这会太过分和多余,如果我选择使用不同的模型,我将不得不修改盒子碰撞器,我想在不指定盒子碰撞器的情况下执行此操作

编辑

我无法为模型添加碰撞器,未来我打算支持允许用户上传模型,其中它自然需要能够与脊椎的select部分进行交互,无需用户为脊柱组件设置边界

对于其他想知道如何做到这一点的人来说,这实际上是半简单的。将此函数放入更新循环中,并使 'SpineRoot' 等于要检查的所有对象的根节点。

public void RegisterSelectControls()
{
    if (Input.GetMouseButtonDown(0))
    {
        var clickLocation = Input.mousePosition;

        Transform closestBone = null;

        this.MinimumRecursiveBoneDistance(clickLocation, SpineRoot, out closestBone);

        if(null != closestBone)
        {
            Debug.Log(closestBone.gameObject.name);
        }
    }
}

public float MinimumRecursiveBoneDistance(Vector3 clickLocation, Transform root, out Transform closestBone)
{
    float minimumDistance = float.MaxValue;
    closestBone = null;
    foreach (Transform bone in root)
    {

        var boneScreenPoint = Camera.main.WorldToScreenPoint(bone.position);
        var distance = Math.Abs(Vector3.Distance(clickLocation, boneScreenPoint));

        if (distance < minimumDistance)
        {
            minimumDistance = distance;
            closestBone = bone;
        }

        if (bone.childCount > 0)
        {
            Transform closestChildBone;
            var minimumChildDistance = this.MinimumRecursiveBoneDistance(clickLocation, bone, out closestChildBone);
            if(minimumChildDistance < minimumDistance)
            {
                minimumDistance = minimumChildDistance;
                closestBone = closestChildBone;
            }
        }

    }

    return minimumDistance;
}

此代码可以进行一些重构,这只是概念验证。这将适用于纯粹最近的。然而,这可能会产生一个潜在的错误,如果单击一个对象,并且该对象的中心离另一个对象的中心更远,那么您将 select 另一个对象。