Unity3d Выберите ближайший объект, чтобы щелкнуть без коллайдеров

У меня есть модель Mixamo, которую я использую для разработки. Эта модель полностью оснащена скелетом. Я пытаюсь создать функцию, которая позволит мне выбрать часть скелета без коллайдера.

Этот Текущий Скрипт работает только с коллайдером,

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);
        }
    }
}

Есть ли способ определить, какая часть скелета была щелчком или ближайшая часть скелета к щелчку?

Я не хочу добавлять коллайдеры к каждой части тела вручную, это было бы слишком избыточно и избыточно, и если я решу использовать другую модель, мне придется модифицировать коллайдеры бокса, я бы хотел сделать это без указания коллайдера бокса.

Изменить

Я не могу добавлять коллайдеры в модели, в будущем я намерен поддерживать разрешение пользователю загружать модель, в которой он должен естественным образом иметь возможность выбирать части позвоночника для взаимодействия, без установки пользователем границ для компонентов модели. позвоночник


person johnny 5    schedule 02.12.2016    source источник
comment
Разные коллайдеры для разных частей тела. answers.unity3d.com/questions/64678/   -  person Chuck Savage    schedule 02.12.2016
comment
поищите в гугле выстрел в голову единства   -  person Chuck Savage    schedule 02.12.2016
comment
да, я знаю, что это будет работать с коллайдерами, однако там слишком много костей, и мне не хочется вручную добавлять коллайдеры для всех из них, я просто хотел бы рассчитать это, зарегистрировав щелчок на 2D-плоскости и найдя ближайший кость туда   -  person johnny 5    schedule 02.12.2016
comment
Все идеи, которые я придумываю, будут работать намного хуже, чем коллайдеры. Я думаю, что было бы проще написать скрипт, который находит кости, назначает коллайдеры и автоматически определяет их размер. Я имею в виду, что у вас в любом случае должен быть доступ к геометрии кости, чтобы вы могли автоматически добавлять коллайдеры.   -  person Rich Joslin    schedule 02.12.2016
comment
у кости миксамо отсутствует полная геометрия, она представлена ​​только преобразованием, положением и вращением. Я подумывал написать для него скрипт, но рассчитать длину будет нормально, а вот ширина коллайдера будет сильно зависеть от модели, я хотел сделать это более универсальным, да и другие досадные проблемы типа если кости вложены рядом друг с другом другое, я пишу это, что было бы более полезно, но я надеялся, что кто-то взломал это или знал о функции, которая уже делает это   -  person johnny 5    schedule 02.12.2016
comment
hit.collider.transform.name -> hit.collider.name   -  person Fredrik Schön    schedule 02.12.2016
comment
@Fredrik, это заставит меня добавить коллайдеры в модель, я намерен разрешить людям загружать свои собственные модели в будущем, а это значит, что я не могу добавлять коллайдеры вручную   -  person johnny 5    schedule 02.12.2016
comment
А, я вижу вашу проблему. Я подумаю об этом. Может быть, скрипт, генерирующий коллайдер? Хе-хе   -  person Fredrik Schön    schedule 02.12.2016
comment
@Fredrik Да, я думал об этом, это может стать немного схематичным, если кости окажутся вложенными, например, при выборе компонентов в голове. Я обсуждал рендеринг изображения, как если бы оно было 2D, и отображение костей на основе перспективы камеры, а затем отслеживание там щелчка до точки на изображении, а затем просто сопоставление его с ближайшим   -  person johnny 5    schedule 02.12.2016
comment
В единстве вам нужны коллайдеры для проверки щелчка forum.unity3d.com/threads/   -  person Get Off My Lawn    schedule 03.12.2016
comment
@GetOffMyLawn Я знаю, что заложено в единстве, я пытаюсь обсудить альтернативные решения   -  person johnny 5    schedule 03.12.2016
comment
Да, согласно указанной ссылке, вам нужно вручную выполнить все вычисления, которые Collier и ray cast делают в единстве.   -  person Get Off My Lawn    schedule 04.12.2016


Ответы (1)


Для всех, кто ищет, как это сделать, это на самом деле полу просто. Включите эту функцию в цикл обновления и сделайте так, чтобы «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;
}

Этот код может использовать некоторый рефакторинг, это было просто доказательство концепции. Это будет работать для чисто ближайших. Однако это может привести к потенциальной ошибке. Если щелкнуть объект, а центр этого объекта находится дальше от щелчка, чем центр другого объекта, вы выберете другой объект.

person johnny 5    schedule 04.12.2016