Rilevamento delle collisioni e risposta in un sistema di entità


12

Più divertimento con un ES ...

Attualmente, ho alcuni sistemi:

  • Renderer (attributo renderizzabile, attributo trasformazione)
  • Movimento (attributo mobile, attributo trasformazione, attributo renderizzabile [per i riquadri di delimitazione, ecc.])
  • Input (attributo InputReceiver)
  • eccetera.

Sto aggiungendo il rilevamento delle collisioni. Il mio primo pensiero è stato quello di aggiungere un nuovo sistema che esegue la collisione. Ha senso per me per mantenere questo isolato dal Motionsistema in quanto non tutte le cose che si muovono o sono animate necessariamente partecipare al rilevamento delle collisioni - telecamere, nebbia, ecc - ma sembra che Collisione Motionsono interdipendenti.

Quando si Motionsposta un'entità, è necessario convalidare la trasformazione Collisione annullare il movimento o modificarlo (rimbalzare, fermarsi contro un muro, ecc.).

Un'alternativa sarebbe quella di creare un attributo Collidable che mantenga un riferimento a un oggetto di collisione - kd-tree, octree, ecc. Che è condiviso tra entità che possono scontrarsi tra loro. Il Motionsistema verifica quindi tale attributo e lo utilizza per verificare o regolare il movimento.

Dal punto di vista del codice, questa è una soluzione accettabile. Tuttavia, dal punto di vista dell'architettura ECS, sembra che stia spingendo la logica nel Motionsistema che non si applica a tutte le entità che hanno un Movableattributo.

Potrei anche memorizzare un vettore di movimento Movablenell'attributo e far Colliderregolare il sistema Transformsecondo necessità, ma ciò comporterà la duplicazione della funzionalità tra Motione Collider, o un callback da Collidera Motioncon alcuni dati sulla posizione di collisione e dati di superficie per rimbalzo / riflessione, ecc. .

Questo potrebbe rientrare nel titolo di "caso speciale hack", ma mi piacerebbe ottenere alcuni input da quelli che hanno gestito questo prima senza creare un sacco di codice del caso limite.

La domanda Qual è un buon modo per evitare l'accoppiamento stretto tra i sistemi di movimento e di collisione quando sembra che richiedano una conoscenza reciproca?


1
Qual'è la domanda?
jcora,

@Bane è un buon posto per mettere la logica di rilevamento delle collisioni, mantenendo la collisione + il movimento il più separati possibile e mantenendo al minimo le interdipendenze tra i sistemi. Il mio post è stato un po '
sconclusionato

1
Fantastico, ora mettilo nella tua domanda, in grassetto . :)
jcora,

Risposte:


7

Lo stai pensando troppo. Nel mio motore, che utilizza anche un sistema di componenti entità, ognuno GameObjectpuò avere un puntatore a ModuleCollision.

Cosa succede quando il gioco si aggiorna:

  • La scena aggiorna tutti gli oggetti che contiene. Chiama la Updatefunzione per ciascuno GameObject.
  • All'interno della Updatefunzione, ognuno aggiorna GameObject solo la sua velocità e direzione, non la sua posizione.
  • GameObjectcarica la sua posizione, velocità e direzione attuali nella sua ModuleCollision, se disponibile.
  • La scena esegue il controllo delle collisioni su ModuleCollisionbase.
  • La scena chiama la UpdatePostfunzione su ciascuno GameObject. Se l'oggetto ha un modulo di collisione, recupera la posizione, la velocità e la direzione aggiornate dal modulo di collisione. La posizione viene aggiornata con la velocità e la direzione.
  • Il GameObjectcostruisce una matrice 3x3 finale dalla sua posizione e voce.

Sì, c'è qualche duplicazione di stato, ma va bene. Fare la gestione delle collisioni su a ModuleCollisionè il modo migliore per farlo, perché altrimenti dovresti controllare ognuno GameObjectper vedere se ha un ModuleCollisionhandle.


2
Quindi, piuttosto che preoccuparti di tornare indietro nella posizione in caso di collisione, stai dividendo la velocità / accelerazione dalla traduzione, alterando quelli basati su eventuali collisioni rilevate, e quindi tali cambiamenti vengono propagati in un secondo aggiornamento specializzato all'interno dello stesso frame? Sembra abbastanza pulito. Grazie.
3Daveva il

3

Lo farei così ...

Hanno tre sistemi:

  1. Sistema di movimento
  2. Sistema di accelerazione
  3. Sistema di collisione

Il sistema di movimento applica velocità alle posizioni. Il sistema di accelerazione applica forze alle velocità. Il sistema di collisione rileva le collisioni e applica le forze nelle giuste direzioni o, se si desidera collisioni grossolane, altera direttamente le velocità.

Ad esempio, è possibile calcolare l'angolo tra le collisioni usando atan2 e quindi utilizzarlo per applicare le forze / velocità corrette ai corpi.

Fare in modo che anche il sistema di rilevamento delle collisioni trasmetta messaggi se necessario.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.