Wykrywanie kolizji i reagowanie w systemie encji


12

Więcej zabawy z ES ...

Obecnie mam kilka systemów:

  • Renderer (atrybut do renderowania, atrybut przekształcenia)
  • Ruch (atrybut ruchomy, atrybut Przekształć, atrybut Renderowalny [dla obwiedni itp.])
  • Dane wejściowe (atrybut InputReceiver)
  • itp.

Dodam wykrywanie kolizji. Moją pierwszą myślą było dodanie nowego systemu, który wykonuje kolizję. Sensowne jest dla mnie trzymanie tego w izolacji od Motionsystemu, ponieważ nie wszystkie rzeczy, które się poruszają lub są animowane, koniecznie uczestniczą w wykrywaniu kolizji - kamery, mgła itp. - ale wydaje się, że Collisioni Motionsą od siebie zależne.

Kiedy Motionporusza się byt, transformacja musi być zatwierdzona Collision, a ruch albo anulowany, albo dostosowany (odbijanie, zatrzymywanie się przy ścianie itp.).

Alternatywą byłoby utworzenie atrybutu Collidable, który zachowuje odniesienie do obiektu kolizyjnego - drzewa kd, oktetu itp., Który jest współużytkowany przez jednostki, które mogą się ze sobą kolidować. MotionSystem będzie wtedy sprawdzać tego atrybutu i użyć go w celu sprawdzenia czy regulować ruch.

Z punktu widzenia kodu jest to akceptowalne rozwiązanie. Jednak z punktu widzenia architektury ECS wydaje się, że wpycha logikę do Motionsystemu, która nie ma zastosowania do wszystkich jednostek, które mają Movableatrybut.

Mógłbym również zapisać w Movableatrybucie wektor ruchu i Colliderdostosować system Transformw razie potrzeby, ale będzie to wymagało duplikowania funkcji pomiędzy Motioni Colliderlub oddzwaniania od Colliderdo Motionz niektórymi danymi o lokalizacji kolizji i danych powierzchni do odbicia / odbicia itp. .

Może to być objęte hasłem „special case hack”, ale chciałbym uzyskać informacje od tych, którzy wcześniej sobie z tym poradzili, bez tworzenia mnóstwa kodu sprawy.

Pytanie Jaki jest dobry sposób na uniknięcie ścisłego połączenia między systemami ruchu i kolizji, gdy wydaje się, że wymagają one wzajemnej wiedzy?


1
Jakie jest pytanie?
jcora,

@Bane, co jest dobrym miejscem na umieszczenie logiki wykrywania kolizji, utrzymywanie kolizji i ruchu możliwie jak najbardziej osobno i utrzymywanie współzależności między systemami na minimalnym poziomie. Mój post był trochę
chaotyczny

1
Świetnie, teraz postaw to w swoim pytaniu, pogrubiona . :)
jcora,

Odpowiedzi:


7

Przemyślasz to. W moim silniku, który również używa systemu element-jednostka, każdy GameObjectmoże mieć wskaźnik do ModuleCollision.

Co się stanie, gdy gra się zaktualizuje:

  • Scena aktualizuje wszystkie posiadane obiekty. Wywołuje Updatefunkcję dla każdego GameObject.
  • Wewnątrz Updatefunkcji każdy aktualizuje GameObject tylko swoją prędkość i kierunek, a nie pozycję.
  • GameObjectprzesyła swoją aktualną pozycję, prędkość i kierunek do ModuleCollision, jeśli jest dostępny.
  • Scena sprawdza na ModuleCollisionpodstawie kolizji .
  • Scena wywołuje UpdatePostfunkcję na każdym z nich GameObject. Jeśli obiekt ma moduł kolizji, pobiera zaktualizowaną pozycję, prędkość i kierunek z modułu kolizji. Pozycja jest aktualizowana o prędkość i kierunek.
  • GameObjectKonstrukcje końcowe macierzy 3x3 z położenia i kierunku.

Tak, jest pewne powielanie stanu, ale nie ma sprawy. Radzenie sobie z kolizjami ModuleCollisionjest najlepszym sposobem na obejście tego, ponieważ w przeciwnym razie trzeba by sprawdzić każdy GameObjectz nich, aby sprawdzić, czy ma on ModuleCollisionuchwyt.


2
Więc zamiast martwić się pozycją cofania w przypadku kolizji, dzielisz prędkość / przyspieszenie z translacji, zmieniając te w oparciu o wykryte kolizje, a następnie zmiany te są propagowane w drugiej specjalnej aktualizacji w tej samej ramce? Wydaje się całkiem czysty. Dzięki.
3Dave

3

Zrobiłbym to w ten sposób ...

Posiadaj trzy systemy:

  1. System ruchu
  2. System przyspieszenia
  3. System kolizji

System ruchu stosuje prędkości do pozycji. Układ przyspieszenia przykłada siły do ​​prędkości. System kolizji wykrywa kolizje i przykłada siły we właściwych kierunkach lub, jeśli chcesz zderzeń pierwotnych, bezpośrednio zmienia prędkości.

Na przykład można obliczyć kąt między zderzeniami za pomocą atan2 , a następnie użyć go do zastosowania odpowiednich sił / prędkości ciał.

Niech system wykrywania kolizji rozsyła również w razie potrzeby komunikaty.

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.