Чому OnCollisionEnter Unity не дає мені нормальних показників поверхні, і який найнадійніший спосіб отримати їх?


11

Подія Unity у зіткненні дає вам об'єкт Зіткнення, який дає вам деяку інформацію про зіткнення, що сталося (включаючи список контактних точок з нормальними попаданнями).

Але те, що ви не отримуєте, - це поверхневі норми для бійця, в який ви потрапили. Ось скріншот для ілюстрації. Червона лінія - від, ContactPoint.normalа синя - від RaycastHit.normal.

введіть тут опис зображення

Це примірник приховування інформації Unity для надання спрощеного API? Або стандартні тривимірні методи виявлення зіткнень у реальному часі просто не збирають цю інформацію?

А для другої частини питання, що є надійним і відносно ефективним способом отримати нормальну поверхню для зіткнення?

Я знаю, що радіомовлення дає вам нормальні показники поверхні, але, здається, мені потрібно виконати декілька радіопередач, щоб досягти цього для всіх сценаріїв (можливо, контактна точка / нормальна комбінація не вистачає колайдера на першому складі, або, можливо, вам потрібно виконати середнє серед усіх норми контактних точок для отримання найкращого результату).

Мій поточний метод:

  1. Створіть резервну копію Collision.contacts[0].pointуздовж її звичайного попадання

  2. Raycast вниз заперечне потрапляння звичайного для float.MaxValue, наCollision.collider

  3. Якщо це не вдається, повторіть кроки 1 і 2 з нормами, які не заперечуються

  4. Якщо це не вдається, спробуйте кроки 1 - 3 Collision.contacts[1]

  5. Повторіть 4, доки не вдасться або поки не будуть вичерпані всі точки контактів.

  6. Відмовтеся, поверніться Vector3.zero.

Це, здається, сприймає все, але всі ці радіопередачі роблять мене неприємним, і я не впевнений, як перевірити, чи працює це на достатню кількість випадків. Чи є кращий спосіб?

EDIT Якщо це дійсно так, як у випадку зіткнення 3D, огляд того, чому в загальному випадку буде так само вітатися, як щось особливе для Unity.


Це просто для цікавості, чи ти намагаєшся щось зробити і застряєш? Тобто, чому ви вважаєте, що поверхня потрібна вам нормально? Задайте питання про те, якого ефекту ви намагаєтеся досягти, а не як «виправити» рішення не визначеної проблеми, і хтось може допомогти вам вирішити. :)
Шон Міддлічч

@SeanMiddleditch Я не згоден. Питання добре поставлено, і саме це я шукав. Це запитання та його відповіді допомогли мені виправити деякі речі, які я робив неправильно.
SteakOverflow

Відповіді:


12

Це справді просто так, як справи зіткнення. Не тільки 3D, але і 2D. Візьмемо такий приклад:

Перекриття AABB

Зелені та червоні AABB стикаються, а контактний колектор - синя зона. Точки контактів будуть десь у синій області (саме там, де це залежить від алгоритму, але кути, де зустрічається синій / червоний / зелений, є ідеальними).

Яку поверхню нормально повернути? Верхній край червоного AABB або лівий край? Якщо зелений ящик падає вниз, можливо, ми можемо обґрунтовано відгадати верхній край. якщо він рухається праворуч, можливо, ми можемо розумно вгадати лівий край. Що робити, якщо він рухався вниз і вправо? Чи візьмемо вісь найменшого проникнення? Вісь швидкості найбільшої швидкості? Деякі евристики обох? Що робити, якщо ящики зіткнулися б точно на кутах?

Розкладіть це на складній тривимірній поверхні, яка потенційно може складатись із 100-х тріс / граней. Ви все ще матимете лише невелику кількість контактних точок з ідеальними результатами. Яку поверхню нормально повернути? Середня нормальна поверхня по всій тримережі (що не має сенсу для більшості об'єктів)? Точки прямо "під" кутами коробки, що стикається (які не визначені для більшості інших фігур)? Ви намагаєтесь знайти найближче обличчя до створених контактних точок (що вимагало б другого проходу, оскільки точки контактів не обчислюються безпосередньо з будь-яких граней сітки)? Якщо ви знайдете найближче обличчя, чи вважаєте ви обличчя нормальним або інтерполюєте вершини обличчя в точці контакту, щоб отримати правильну норму для "гладких" об'єктів?

Дійсно, головна проблема полягає в тому, що точки контакту - це не всі точки контакту. У багатьох випадках це був би нескінченний набір точок. Це лише декілька точок, які добре розподілені, які роблять обґрунтовано можливим наблизити фізичну реакцію, застосовуючи сили у зазначених точках, щоб підштовхувати об'єкти, що стикаються, повторно повторюючись. Конкретні точки / місця фактичного контакту об'єкта відбираються за спрощеною математичною моделлю. Отже, уявлення про конкретну поверхню, нормальної контакту, просто не має великого сенсу в загальному випадку.

Звичайно, маючи більш конкретні обмеження та обмеження щодо ваших об'єктів, світу та руху, ви можете створити альтернативні алгоритми зіткнення, які можуть розповісти про нормальну поверхню. У випадку 2D вище, якщо припустити, що поля ніколи не обертаються і що ми знаємо відносну швидкість і останнє положення кожного, можна було б використовувати безперервне виявлення зіткнення, щоб точно з’ясувати, коли вони зіткнулися і які особливості зіткнулися, постачаючи нам точна особливість, коли сталося зіткнення, яке потім може бути використане як нормальний контакт / зіткнення / поверхня. Ігри платформерів повністю побудовані на таких припущеннях і спеціальних хитрощах (саме тому використання загальної бібліотеки фізики, наприклад Box2D або Havok, або світла ніколи не створює такого жорсткого, точного управління, яке ви знайдете у класичних платформерів, таких як Mario або Sonic; я б не став хочу сказати це '

Загальні бібліотеки фізики Ньютона, як і ті, що використовуються в Unity3D, не можуть робити подібні спрощення та припущення. Звідси ви не отримуєте нормалів поверхні зіткнення, ви отримуєте контактний колектор, як правило, спрощений до точок контактів, і все.


Це фантастична відповідь, і саме те, що я шукав, дякую. Конкретною проблемою було отримання переконливого вектора відбиття на кінематичному жорсткому тілі при зіткненні. Це звичайний підхід, якщо ви хочете, щоб ця інформація вибирала, чи потрібно випромінювати або брати 3 контактних точки (якщо вони доступні) та брати перехресний продукт?
michael.bartnett
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.