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 Motion
systemu, ponieważ nie wszystkie rzeczy, które się poruszają lub są animowane, koniecznie uczestniczą w wykrywaniu kolizji - kamery, mgła itp. - ale wydaje się, że Collision
i Motion
są od siebie zależne.
Kiedy Motion
porusza 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ć. Motion
System 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 Motion
systemu, która nie ma zastosowania do wszystkich jednostek, które mają Movable
atrybut.
Mógłbym również zapisać w Movable
atrybucie wektor ruchu i Collider
dostosować system Transform
w razie potrzeby, ale będzie to wymagało duplikowania funkcji pomiędzy Motion
i Collider
lub oddzwaniania od Collider
do Motion
z 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?
Odpowiedzi:
Przemyślasz to. W moim silniku, który również używa systemu element-jednostka, każdy
GameObject
może mieć wskaźnik doModuleCollision
.Co się stanie, gdy gra się zaktualizuje:
Update
funkcję dla każdegoGameObject
.Update
funkcji każdy aktualizujeGameObject
tylko swoją prędkość i kierunek, a nie pozycję.GameObject
przesyła swoją aktualną pozycję, prędkość i kierunek doModuleCollision
, jeśli jest dostępny.ModuleCollision
podstawie kolizji .UpdatePost
funkcję na każdym z nichGameObject
. 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.GameObject
Konstrukcje końcowe macierzy 3x3 z położenia i kierunku.Tak, jest pewne powielanie stanu, ale nie ma sprawy. Radzenie sobie z kolizjami
ModuleCollision
jest najlepszym sposobem na obejście tego, ponieważ w przeciwnym razie trzeba by sprawdzić każdyGameObject
z nich, aby sprawdzić, czy ma onModuleCollision
uchwyt.źródło
Zrobiłbym to w ten sposób ...
Posiadaj trzy systemy:
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.
źródło