Come dovrei implementare la "consapevolezza" nemica delle unità?


12

Sto usando Unity3d per sviluppare un gioco prototipo ibrido RTS / TD. Qual è l'approccio migliore per la "consapevolezza" tra le unità e i loro nemici? È ragionevole che ogni unità controlli la distanza da ogni nemico e si impegni se si trova nel raggio di azione?

L'approccio che sto cercando in questo momento è di avere una sfera di innesco su ogni unità. Se un nemico entra nel grilletto, l'unità diventa consapevole del nemico e inizia il controllo della distanza. Ciò consente di risparmiare alcuni controlli inutili?

Qual è la migliore pratica qui?


Vorrei aggiungere che il conteggio unità / nemico sarà nella scala del Comandante Supremo
Phil,

Risposte:


10

Cerca nelle gerarchie di volumi limitanti (BVH). Sono più comunemente utilizzati nel rilevamento delle collisioni per ridurre il numero di controlli necessari nel calcolo delle collisioni o nel rendering per eseguire l'abbattimento del frustum sugli oggetti. Dato che stai già utilizzando le sfere, suggerirei un albero a sfera sebbene altri volumi come AABB possano essere più efficienti. Non sono sicuro del tipo di supporto che Unity offre per cose che non l'ho mai usato, ma probabilmente c'è qualcosa per questo già nel rilevamento delle collisioni o nel rendering di parti del motore.

Fondamentalmente, vorresti raggruppare i nemici vicini l'uno all'altro in più sfere genitore. Quando un'unità viene mossa, verifichi che sia la sfera di innesco contro la sfera madre invece di controllare ogni nemico. Se la sfera del grilletto si interseca con la sfera del genitore, dovresti controllare ogni nemico all'interno. In caso contrario, puoi scartare tutti i nemici che si trovano al suo interno. Si desidera impostare più livelli di sfere in base alla dimensione massima di una sfera o al conteggio dei nemici per ciascuna sfera ed eseguire il controllo in base a una sfera di livello superiore. Quindi è solo una questione di camminare lungo l'albero per controllare ogni nemico senza dover eseguire il controllo della distanza per ognuno.

Passaggi richiesti per ogni frame:

  1. Sposta i nemici
  2. Ricostruisci / aggiorna il BVH per nuove posizioni nemiche
  3. Sposta le unità e controlla contro l'albero delle sfere.

Questo può ridurre i controlli necessari quando ci sono molti nemici, ma il sovraccarico di aggiornamento e memorizzazione dell'albero potrebbe non valerne la pena quando non ce ne sono molti. Non ho familiarità con il Comandante Supremo per sapere cosa stai cercando, quindi presumo solo "centinaia". Dovrai profilare in diverse situazioni per scoprire se il sovraccarico ne varrà la pena.


3
+1 questo approccio sarà più semplice anche se avrà alcuni errori. OP potrebbe voler implementare questo e quindi implementare qualcosa come un ottetto. Inoltre, nella maggior parte degli RTS, le unità reagiscono con un certo ritardo. In effetti, la maggior parte dell'intelligenza artificiale nei giochi viene calcolata 10-30 fotogrammi al secondo in cui il gioco può essere eseguito a 30-60 fotogrammi al secondo (i numeri sono, ovviamente, approssimazioni).
Samaursa,

Grazie, questo era esattamente ciò di cui avevo bisogno per farmi un passo avanti. Cercherò BVH e come implementarlo in Unity. Post molto pedagogico e informativo! +1
Phil

Oh, e controlla il Comandante Supremo se sei in RTS. È davvero un bel gioco, come lo sono tutti i giochi di Chris Taylor.
Phil

7

Non è necessario implementare BVH, poiché il motore di collisione di Unity lo fa già per te.

Basta attaccare un grande grilletto a sfera perimetrale a ciascuna unità (che rappresenta il suo raggio) e gestire i callback OnCollisionEnter()e OnCollisionExit()per tenere traccia di quali nemici si trovano nel raggio di ogni unità.

Nota che il caso che ti interessa è quando un'altra unità si scontra con la sfera, non quando la sfera di un'altra unità si scontra con la sfera.


1
Penso che questo debba essere votato almeno sopra la risposta accettata. La risposta accettata è buona per lo studio, ma questa risposta dovrebbe essere al top in quanto questo è il modo più pratico.
Varaquilex,

Credo che tu intenda OnTriggerEnter()e OnTriggerExit(), giusto?
Jibb Smart,

1

Un'altra soluzione che si adatta molto bene e può essere utilizzata per una moltitudine di altre cose è una mappa influeunce. Genera una serie di riquadri della griglia attorno all'unità per scansionare entro il raggio X. Scansiona queste tessere per individuare un nemico in piedi su una di esse. Se vuoi ottenere i nemici più vicini, puoi ordinare il tuo set per distanza.

Questo potrebbe essere il metodo più efficiente, specialmente se hai intenzione di fare altre cose con la mappa delle influenze come nebbia di guerra o ricerca di percorsi.

Ecco un video che ho realizzato per spiegare il concetto: https://www.youtube.com/watch?v=MEd6XV2Pecw .

Ed ecco un'implementazione: https://www.youtube.com/watch?v=y_ewoxlZlgc

Consiglio di non inizializzare la raccolta di unità del riquadro della griglia all'avvio, ma solo quando è necessaria la raccolta.

In alternativa, puoi usare una matrice di lunghezza X se sai che non ci saranno mai più di X unità su una tessera.

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.