Dlaczego UnCity OnCollisionEnter nie podaje normalnych powierzchni i jaki jest najbardziej niezawodny sposób ich uzyskania?


11

Zdarzenie Unity dotyczące kolizji daje ci obiekt kolizji, który daje pewne informacje na temat kolizji, która miała miejsce (w tym listę punktów kontaktowych z normalnymi trafieniami).

Ale nie dostajesz normalnych powierzchni dla zderzacza, który trafiłeś. Oto zrzut ekranu do zilustrowania. Czerwona linia pochodzi z, ContactPoint.normala niebieska linia pochodzi z RaycastHit.normal.

wprowadź opis zdjęcia tutaj

Czy jest to przykład ukrywania informacji w Unity w celu zapewnienia uproszczonego interfejsu API? A może standardowe techniki wykrywania kolizji w czasie rzeczywistym 3D po prostu nie zbierają tych informacji?

A jeśli chodzi o drugą część pytania, jaki jest pewny i stosunkowo skuteczny sposób na uzyskanie normalnej powierzchni na wypadek kolizji?

Wiem, że raycasting daje ci normalne na powierzchni, ale wydaje się, że muszę zrobić kilka raycastów, aby osiągnąć to we wszystkich scenariuszach (może punkt kontaktowy / normalna kombinacja nie trafia w zderzacz przy pierwszym rzucie, a może musisz zrobić jakąś średnią ze wszystkich normalne punkty kontaktowe, aby uzyskać najlepszy wynik).

Moja obecna metoda:

  1. Wykonaj kopię zapasową Collision.contacts[0].pointwzdłuż jej normalnego poziomu

  2. Raycast w dół zanegowane trafienie normalne float.MaxValue, naCollision.collider

  3. Jeśli to się nie powiedzie, powtórz kroki 1 i 2 z niez negowanym normalnym

  4. Jeśli to się nie powiedzie, spróbuj wykonać kroki od 1 do 3 za pomocą Collision.contacts[1]

  5. Powtarzaj 4, aż się powiedzie lub do wyczerpania wszystkich punktów kontaktowych.

  6. Poddaj się, wróć Vector3.zero.

Wydaje się, że to wszystko łapie, ale wszystkie te raycaste powodują, że mam mdłości i nie jestem pewien, jak sprawdzić, czy działa to w wystarczającej liczbie przypadków. Czy jest lepszy sposób?

EDYCJA Jeśli tak właśnie jest z kolizją 3D, przegląd tego, dlaczego w ogólnym przypadku byłby tak samo mile widziany, jak coś specyficznego dla Unity.


Czy to tylko z ciekawości, czy próbujesz coś zrobić i utknąć? To znaczy, dlaczego uważasz, że potrzebujesz normalnej powierzchni? Zadaj pytanie o efekt, który próbujesz osiągnąć, a nie o to, jak „naprawić” rozwiązanie nieokreślonego problemu, a ktoś może pomóc ci go rozwiązać. :)
Sean Middleditch

@SeanMiddleditch Nie zgadzam się. Pytanie jest dobrze postawione i właśnie tego szukałem. To pytanie i odpowiedzi pomogły mi poprawić niektóre rzeczy, które robiłem źle.
SteakOverflow 22.04.16

Odpowiedzi:


12

Tak naprawdę dzieje się tak w przypadku kolizji. Nie tylko 3D, ale także 2D. Weź następujący przykład:

Nakładające się AABB

Zielone i czerwone AABB zderzają się, a kolektor stykowy to niebieski obszar. Punkty kontaktowe będą znajdować się gdzieś w niebieskim obszarze (dokładnie gdzie może się różnić w zależności od algorytmu, ale rogi, w których spotykają się niebieski / czerwony / zielony, są idealne).

Jaką normalną powierzchnię należy zwrócić? Górna krawędź czerwonego AABB czy lewa krawędź? Jeśli spadnie zielone pole, być może uda nam się odgadnąć górną krawędź. jeśli porusza się w prawo, być może uda nam się odgadnąć lewą krawędź. Co jeśli poruszał się w dół i dobrze? Czy przyjmujemy oś najmniejszej penetracji? Oś prędkości największej prędkości? Jakaś heurystyka obu? Co by było, gdyby pudła zderzyły się dokładnie na rogach?

Rozszerz to na złożoną powierzchnię 3D potencjalnie złożoną z setek tris / ścian. Nadal będziesz mieć tylko niewielką liczbę idealnych punktów kontaktowych. Jaką normalną powierzchnię należy zwrócić? Czy średnia normalna powierzchnia na całej siatce trójsiatkowej (co nie ma sensu dla większości obiektów)? Punkty bezpośrednio „pod” rogami kolizji (które nie są dobrze zdefiniowane dla większości innych kształtów)? Czy próbujesz znaleźć najbliższą powierzchnię do wygenerowanych punktów kontaktowych (co wymagałoby drugiego przejścia, ponieważ punkty kontaktowe nie są obliczane bezpośrednio z żadnych ścian siatki)? Jeśli znajdziesz najbliższą twarz, czy bierzesz normalną twarz, czy interpolujesz jej wierzchołki w punkcie styku, aby uzyskać prawidłową normalną dla „gładkich” obiektów?

Naprawdę głównym problemem jest to, że punkty kontaktowe nie są wszystkimi punktami kontaktowymi. W wielu przypadkach byłby to jednak nieskończony zestaw punktów. To tylko kilka punktów, które są dobrze rozmieszczone, co umożliwia racjonalne przybliżenie reakcji fizycznej poprzez zastosowanie sił w tych punktach, aby popchnąć zderzające się obiekty w sposób realistyczny. Konkretne punkty / lokalizacje faktycznego kontaktu z obiektem są wyodrębnione za uproszczonym modelem matematycznym. Dlatego idea określonej normalnej powierzchni kontaktu po prostu nie ma większego sensu w ogólnym przypadku.

Oczywiście, dzięki bardziej szczegółowym ograniczeniom i ograniczeniom dotyczącym twoich obiektów, świata i ruchu, możesz stworzyć alternatywne algorytmy kolizji, które powiedzą ci o normalnej powierzchni. W powyższym przypadku 2D, jeśli założymy, że pola nigdy się nie obracają i znamy względną prędkość i ostatnią pozycję każdego z nich, mogliby użyć ciągłego wykrywania kolizji, aby dowiedzieć się dokładnie, kiedy się zderzą i które cechy zderzyły się, dostarczając nam dokładna cecha, w której doszło do kolizji, którą można następnie wykorzystać jako kontakt / kolizję / normalną powierzchnię. Gry platformowe są zbudowane w całości na takich założeniach i specjalnych sztuczkach (dlatego użycie ogólnej biblioteki fizyki, takiej jak Box2D lub Havok, lub światło nigdy nie zapewnia takiej ścisłej, precyzyjnej kontroli, jaką można znaleźć w klasycznych platformówkach, takich jak Mario lub Sonic; chcę to powiedzieć

Ogólne biblioteki fizyki newtonowskiej, takie jak te używane w Unity3D, nie mogą robić tego rodzaju uproszczeń i założeń. Dlatego nie otrzymujesz normalnych powierzchni kolizji, dostajesz kolektor kontaktowy, ogólnie uproszczony do punktów kontaktowych i to wszystko.


To fantastyczna odpowiedź i właśnie tego szukałem, dziękuję. Konkretnym problemem było uzyskanie przekonującego wektora odbicia na kinematycznym sztywnym ciele podczas zderzenia. Czy jest to zwykłe podejście, jeśli chcesz, aby tego rodzaju informacje decydowały, czy chcesz raycast, czy zdobyć 3 punkty kontaktowe (jeśli są dostępne) i wziąć produkt krzyżowy?
michael.bartnett
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.