Kollisionserkennung und -reaktion in einem Entitätssystem

12

Mehr Spaß mit einem ES ...

Derzeit habe ich ein paar Systeme:

  • Renderer (Attribut "Renderbar", Attribut "Transformieren")
  • Bewegung (Attribut "Verschiebbar", Attribut "Transformieren", Attribut "Renderbar" [für Begrenzungsrahmen usw.])
  • Eingabe (InputReceiver-Attribut)
  • etc.

Ich füge die Kollisionserkennung hinzu. Mein erster Gedanke war, ein neues System hinzuzufügen, das Kollisionen ausführt. Es macht Sinn für mich diese aus dem isoliert zu halten MotionSystem aller Dinge , da sie nicht bewegen oder notwendigerweise in Kollisionserkennung teilnehmen animiert - Kameras, Nebel, etc. - aber es scheint , dass Collisionund Motionvoneinander abhängig sind.

Wenn Motionein Objekt bewegt wird, muss die Transformation mit validiert Collisionund die Bewegung entweder abgebrochen oder angepasst werden (Prellen, Anhalten an einer Wand usw.).

Eine Alternative wäre, ein Collidable-Attribut zu erstellen, das einen Verweis auf ein Kollisionsobjekt - kd-tree, octree usw. - verwaltet, das von Entitäten gemeinsam genutzt wird, die miteinander kollidieren können. Das MotionSystem würde dann nach diesem Attribut suchen und es verwenden, um die Bewegung zu überprüfen oder anzupassen.

Aus Code-Sicht ist das eine akzeptable Lösung. Aus Sicht der ECS-Architektur scheint es jedoch so zu sein, dass Logik in das MotionSystem hineingeschoben wird, die nicht für alle Entitäten gilt, die ein MovableAttribut haben.

Ich könnte auch einen Bewegungsvektor in dem MovableAttribut speichern und das ColliderSystem Transformnach Bedarf anpassen lassen , aber dazu gehört das Duplizieren von Funktionen zwischen Motionund Collideroder ein Rückruf von Colliderbis Motionmit einigen Daten über den Kollisionsort und Oberflächendaten für Abprall / Reflexion usw .

Dies mag unter die Überschrift "Special Case Hack" fallen, aber ich möchte einige Eingaben von denen erhalten, die dies zuvor behandelt haben, ohne eine Tonne Edge-Case-Code zu erstellen.

Die Frage Was ist ein guter Weg, um eine enge Kopplung zwischen Bewegungs- und Kollisionssystemen zu vermeiden, wenn sie scheinbar voneinander Kenntnis benötigen?

3Dave
quelle
1
Was ist die Frage?
JCORA
@Bane Was ist ein guter Ort, um die Kollisionserkennungslogik so weit wie möglich voneinander zu trennen und die gegenseitigen Abhängigkeiten zwischen Systemen so gering wie möglich zu halten. Mein Beitrag war ein bisschen wie ein Streifzug ...
3Dave
1
Großartig, jetzt stell das in deine Frage, mutig . :)
jcora

Antworten:

7

Sie überdenken es. In meiner Engine, die auch ein Entity-Component-System verwendet, GameObjectkann jeder einen Zeiger auf a haben ModuleCollision.

Was passiert, wenn das Spiel aktualisiert wird:

  • Die Szene aktualisiert alle darin enthaltenen Objekte. Es ruft die UpdateFunktion für jeden auf GameObject.
  • Innerhalb der UpdateFunktion aktualisiert jeder GameObject nur seine Geschwindigkeit und Richtung, nicht seine Position.
  • GameObjectlädt seine aktuelle Position, Geschwindigkeit und Richtung hoch ModuleCollision, falls verfügbar.
  • Die Szene führt die Kollisionsprüfung auf einer ModuleCollisionBasis durch.
  • Szene ruft jeweils die UpdatePostFunktion auf GameObject. Wenn das Objekt ein Kollisionsmodul hat, ruft es die aktualisierte Position, Geschwindigkeit und Richtung vom Kollisionsmodul ab. Die Position wird mit der Geschwindigkeit und Richtung aktualisiert.
  • Das GameObjectKonstrukt erstellt eine endgültige 3x3-Matrix aus seiner Position und Überschrift.

Ja, es gibt einige Überschneidungen, aber das ist in Ordnung. Das Kollisionshandling auf a ModuleCollisionist der beste Weg, um dies zu tun , da Sie sonst prüfen müssten GameObject, ob es einen ModuleCollisionHandle hat.

knight666
quelle
2
Sie müssen sich also nicht um die Position der Rückverfolgung im Falle einer Kollision kümmern, sondern die Geschwindigkeit / Beschleunigung von der Übersetzung trennen und die Änderungen basierend auf erkannten Kollisionen ändern. Diese Änderungen werden dann in einem zweiten speziellen Update innerhalb desselben Frames weitergegeben. Scheint ziemlich sauber zu sein. Vielen Dank.
3Dave
3

Ich würde es so machen ...

Habe drei Systeme:

  1. Bewegungssystem
  2. Beschleunigungssystem
  3. Kollisionssystem

Das Bewegungssystem wendet Geschwindigkeiten auf Positionen an. Das Beschleunigungssystem übt Kräfte auf Geschwindigkeiten aus. Das Kollisionssystem erkennt Kollisionen und wendet die Kräfte in die richtigen Richtungen an. Wenn Sie grobe Kollisionen wünschen, werden die Geschwindigkeiten direkt geändert.

Sie können beispielsweise den Winkel zwischen den Kollisionen mit atan2 berechnen und dann verwenden, um die richtigen Kräfte / Geschwindigkeiten auf die Körper anzuwenden.

Lassen Sie das Kollisionserkennungssystem bei Bedarf auch Nachrichten senden.

jcora
quelle