Проблема с обнаружением столкновения быстро движущегося мяча с ракеткой, управляемой мышью - PullRequest
9 голосов
/ 09 сентября 2011

В единстве у меня есть ракетка, которая должна ударить по мячу, и ракетка управляется непосредственно мышью, т. Е. Летучая мышь перемещается мышью с помощью осей мыши и с помощью функции transform.translate () для переместите ракетку.

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

Но столкновение мяча не определяется должным образом, когда ракетка движется. Когда все еще, все хорошо, и мяч ведет себя так, как мне нравится.

Теперь я дошел до того, что написал собственный физический скрипт (я использую C # для написания скриптов), в котором я прикрепил к мячу 4 лучевых трансляции длиной 0,6F, и, выполнив некоторые сложные векторные вычисления, рассчитал скорость мяча после ударяя ракетку, и примените ее непосредственно к скорости мяча, используя hardbody.velocity = calculateVelocity (). Теперь он снова работает нормально, когда ракетка не движется, но не когда я двигаю ракетку. Точная (симптомы) проблемы:

Использование встроенной физики и обнаружения столкновений: когда ракетка движется, мяч иногда проходит прямо через ракетку, а иногда замедляется (до невероятных уровней).

Использование моего скрипта для расчета скорости: проблема та же, но она позволяет мне определить, что не так, когда я печатаю нормаль коллайдера (ракетки). Иногда он дает правильную нормаль, а иногда дает отрицательный вектор нормали, что означает, что он проходит прямо через верхнюю поверхность и обнаруживает попадание с нижней стороны коллайдера (ракетки).

То, что я пробовал:

  1. Увеличение размера коллайдера (он работает с более широким коробчатым коллайдером на ракетке, но затем, очевидно, мяч перемещается на довольно большое расстояние от ракетки, и мой собственный сценарий работает здесь, физика по умолчанию дает странные результаты, когда ракетка перемещается), короче говоря, я не понимаю, чего хочу.

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

  3. Изменение обнаружения столкновений на непрерывную динамику. Что тоже не улучшило ситуацию.

И в дополнение к неправильной стороне, выбранной при столкновении, я заметил еще одну проблему: после отскока от ракетки мяч движется, но ракетка движется быстрее, вместо того, чтобы двигаться по полной дуге или линии. появляется перед мячом, в результате чего два удара. Это гипотеза, основанная на том, что видно.

Также ясно, что аспект "движения" ракетки не читается встроенной физикой Unity3d, что приводит к странному поведению, когда ракетка движется с помощью мыши, ударяющей по мячу.

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

Ответы [ 4 ]

8 голосов
/ 10 сентября 2011

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

Существует три очень простых решения этой проблемы:

  • Увеличьте размер площадки или мяча, чтоэто то, что произошло, когда вы изменили размер коллайдера.
  • Установите максимальную скорость мяча, чтобы он никогда не мог двигаться достаточно быстро, чтобы пройти через пэды.
  • Увеличьте частоту, с которой Unityделает свои физические расчеты.Его можно изменить в Диспетчер времени , уменьшив значение Фиксированного временного шага.Остерегайтесь слишком сильного уменьшения, иначе физический движок не сможет завершить вызов до начала следующего раунда, и он никогда не сможет догнать игру.

НастройкаМаксимальная скорость для движущихся объектов - это то, что всегда нужно делать.Вы не можете рисковать взлетом важного объекта во время игры и оставлять все в неконтролируемом состоянии.

5 голосов
/ 10 сентября 2011

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

1) Ball before racquet 
2) Ball after racquet 

not

1) Ball before racquet 
2) Ball touching racquet 

То, что вам нужно сделать, это в вашем методе FixedUpdate () вашего шара. GameObject направляет луч из текущего местоположения шарика в предыдущее местоположение шарика.Если есть что-то между этими двумя точками, которые должны были быть поражены (например, ракетка), переместите мяч обратно в указанную точку попадания на луче.Это запустит ваши существующие средства обнаружения столкновений.

Причина, по которой увеличение размера коллайдера также работает, заключается в том, что мяч не пропускает коллайдер лагера.Это имеет недостатки, которые вы упомянули в своем вопросе.Применение лучей позволяет избежать этой проблемы и позволяет мячу / ракетке двигаться так быстро или медленно, как им нужно.

3 голосов
/ 09 сентября 2011

Это не полный ответ, но я помню, как сталкивался с такой проблемой много лет назад на медленных машинах.

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

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

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

0 голосов
/ 04 апреля 2014

Я также работал над игрой в 3d-понг и столкнулся с точно такими же проблемами. Я постараюсь расширить все как вы, ребята. Что касается весла, добавляющего скорость и вращение к мячу, я был озадачен этим, пока не понял, что изменение положения весла не меняет его скорость. Если весло было на нулевой скорости, прежде чем оно было перемещено, оно будет на нуле, когда физический движок смотрит на него в следующем кадре. Непроверенная проверка является кениматической, и управление веслом непосредственно через свойство скорости устранило проблему. Это вызвало дрожание затвора при ударе о стены, но я исправил это, удалив стены из слоя затвора и обработав границы вручную в LateUpdate. Кроме того, когда вы обновляете скорость, сначала сохраните новую желаемую скорость в Update, чтобы элементы управления работали плавно, затем зафиксируйте изменения в FixedUpdate.

...