Я не понимаю RaycastCommand - PullRequest
       5

Я не понимаю RaycastCommand

0 голосов
/ 22 января 2020

Документация (https://docs.unity3d.com/2019.2/Documentation/ScriptReference/RaycastCommand.html) гласит:

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

Су, имеющий

new RaycastCommand(from, direction, 4);
  1. Как я могу различить guish, если у меня не было хитов против, когда результат недействителен? Оба случая имеют hit.collider == null.
  2. Если столкнется с несколькими элементами, а не будет возвращать ближайший элемент столкновения, он ничего не вернет ??

1 Ответ

1 голос
/ 22 января 2020

RaycastHit является типом struct, поэтому само по себе никогда не может быть null. Итак, как написано в документах:

Первый недопустимый результат определяется коллайдером как null.


ПРИМЕЧАНИЕ : Порядок (необязательных) параметров в конструкторе , если не указано явно, -

new RaycastCommand(Vector3 from, Vector3 direction, float distance, int layerMask, int maxHits);

и их значения по умолчанию

  • distance = float.MaxValue
  • layerMask = -5
  • maxHits = 1

Снова в словах: Значение по умолчанию для maxHits равно 1!

К сожалению, этого не видно в Документы, кроме вашей IDE, должны раскрыть это.


Зная это сейчас, вы можете видеть, что ваш текущий пример

new RaycastCommand(from, direction, 4);

фактически говорит: Максимальное расстояние луча составляет 4, но все еще допускает только 1 одиночный удар !

Если вы предпочитаете иметь 4 возможных попаданий, вы должны назвать его как

new RaycastCommand(from, direction, maxHits: 4);

теперь, если вы так его называете, будет создан буфер с точно 4 RaycastHit записями, независимо от того, сколько объектов ударили или вообще их ударили.


Тогда вообще ничего не ударили, если

results[0].collider == null

и, к сожалению,

Второй и более поздние недействительные результаты не записываются командой raycast, поэтому их коллайдеры не гарантированно равны null.

вы должны будете отфильтровать их, например, как

var validResults = new List<RaycastHit>();
foreach(var r in results)
{
    if(r.collider == null) break;

    validResults.Add(r);
}

Затем вы можете также отсортировать их по «ближайшему первому», используя Linq, например,

using System.Linq;

...

var orderedResults = validResults.OrderBy(r=>r.distance).ToList();

// Which is basically a shorthand for something like the following
// not sure though how Linq does it internally, I hope it does something more efficient ^^
var orderedResults = new List<RaycastHit>();
foreach(var r in validResults)
{
    for(int i = 0; i < orderedResults.Count; i ++)
    {
        if(orderedResults[i].distance <= r.distance)
        {
            orderesResult.Insert(i + 1, r);
            break;
        }
    }
}
...