2016-12-02 4 views
1

У меня есть модель Mixamo, которую я использую для разработки. Эта модель полностью оснащена скелетом. Я пытаюсь создать функцию, которая позволит мне выбрать кусок скелета без коллайдера.Unity3d Выберите объект, ближайший к клику no colliders

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

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

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

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

Редактировать

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

+0

Различные коллайдеры для различных частей тела. http://answers.unity3d.com/questions/64678/head-shot-instant-kill-for-fps-enemies.html –

+0

поиск google для «единственного выстрела головы» –

+0

да, я знаю, что это будет работать с коллайдерами, однако там слишком много костей, и я не чувствую, что вручную добавляю коллайдеры для всех из них, я просто хотел бы рассчитать это, зарегистрировав щелчок на 2-й плоскости и найдя там ближайшую кость –

ответ

2

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

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

Смежные вопросы