Progettazione basata su componenti / entità + alberi del comportamento => come integrare?


9

Per il mio attuale progetto ho implementato un sistema basato su componenti / entità , sostanzialmente seguendo la maggior parte delle migliori pratiche che esiste in questa area piuttosto indefinita .

Quindi ho ottenuto entità (leggermente estese) , che sono fondamentalmente un intID, un nome leggibile dall'uomo, una std::mapdi componenti e un long"indicatore di tipo" che viene utilizzato per mostrare quali componenti sono presenti (ho una potenza di due enumper tutti i componenti tipi e ogni volta che un componente viene aggiunto all'entità, lo altero automaticamente tramite operazioni bit a bit, confrontando questa risposta ).

Poi ci sono i Componenti , anche piuttosto semplici: intID, enumcome tipo di componente, puntatore Entità padre e una std::mapdi tutte le proprietà di questo componente.

Infine alcuni sistemi / gestori che gestiscono l'elaborazione logica effettiva. Prima controllano se l'Entità attualmente elaborata ha un long"indicatore di tipo" corrispondente = sono presenti tutti i componenti necessari per quel sistema. Quindi accede ad alcune proprietà se necessario e chiama direttamente alcune funzioni nel rispettivo componente o invia alcuni messaggi (tramite un dispatcher di messaggi).

In conclusione: Fino a qui, un sistema basato su componenti / entità basato su eventi piuttosto standard combinato con un approccio basato sui dati (confronto, i componenti non hanno variabili di dati codificate, ma invece una mappa generica, come (alcuni) componenti / archetipi di componenti verranno successivamente letti dai file con l'opzione per aggiungere ulteriori dati, che non fa parte del codice componente effettivo.

Ora vorrei introdurre anche alberi del comportamento (basati su AiGameDev BTSK ) in quel progetto, ma non sono sicuro se e come debbano essere collegati ai componenti già esistenti o come integrare tali progetti in generale.

Vengono in mente diverse idee / punti / domande correlate:

  1. I miei BT verranno letti dai file (di nuovo). Al momento non riesco a capire come farei meglio la connessione tra un BT Actionalbero e la codifica effettiva nella mia applicazione. Dovrei creare una sorta di mappa tra i nomi delle azioni utilizzati nei file BT e un puntatore a funzione per l'implementazione della logica effettiva? Qual è il solito approccio per risolverlo?

  2. Presumo che dovrò creare BT per tutti i miei diversi Entitytipi (quindi per ogni combinazione di componenti di logica di gioco / AI rilevante come indicato dal mio "indicatore di tipo" più volte citato). Di conseguenza non ha senso inserire le BT Actionimplementazioni nei componenti, poiché molto probabilmente saranno coinvolti molti componenti per azione, vero?

  3. Quindi la BT Actionlogica dovrebbe trovarsi in un / più sistemi separati (ai cui metodi punta la mappa dall'idea n. 1)? Il sistema verificherebbe quindi, secondo il mio long"indicatore di tipo", se il EntityBT per il quale è attualmente controllato e che gli è stato detto di eseguire una determinata azione (= metodo nel sistema) sia effettivamente autorizzato a farlo (= ha i componenti necessari). Ma in caso contrario (perché, ad esempio, il creatore di BT ha trascurato una situazione specifica, in cui un componente necessario potrebbe non essere più collegato all'entità in fase di esecuzione), non accadrebbe nulla.

Domande:

  • Esistono concetti comprovati per quel tipo di integrazione?
  • Qual è la tua opinione sui miei 3 punti sopra?
  • Altre cose che mi vengono in mente, anche per quanto riguarda la progettazione basata su componenti / entità in generale?

Per quanto riguarda il punto 1: gli alberi del comportamento non sono altro che un DSL visivo usato principalmente per creare comportamenti dei personaggi. Un componente BehaviorTree non dovrebbe fare nulla di più o di meno di quanto farebbe un componente Script. Per quanto riguarda il punto 3: qual è la ragione per usare una mappa su campi regolari?
Eric

# 1: Cosa significa "DSL" in questo contesto? # 3: Mi dispiace, ma non posso seguirti su questo. Ti interessa spiegare per favore cosa intendi?
Philip Allgaier,

1
probabilmente il linguaggio specifico del dominio, ad es. una sintassi personalizzata per lavorare con un problema molto specifico.
Patrick Hughes,

Patrick ha ragione, sebbene anche una semantica ne faccia parte e "molto" potrebbe essere abbandonato da questa definizione. - Ri 3: Mi scuso, si dovrebbe leggere: "Qual è la ragione per usare una mappa su campi regolari nei componenti ?"
Eric

Ri 3: Voglio la possibilità di specificare in seguito in modo dinamico proprietà aggiuntive al di fuori del codice C ++ (parola d'ordine: data driven). Per semplicità, io (almeno per ora) inserisco tutte le proprietà in questo framework generico (usando le mappe), anche quelle che sono state corrette nel codice e quindi potrebbero essere dei veri campi C ++. Potrebbe essere necessario rivederlo in un secondo momento, se diventa un problema di prestazioni ...
Philip Allgaier,

Risposte:


2

Attualmente non riesco a capire come farei meglio la connessione tra un'azione BT in quell'albero e la codifica effettiva nella mia applicazione. Dovrei creare una sorta di mappa tra i nomi delle azioni utilizzati nei file BT e un puntatore a funzione per l'implementazione della logica effettiva? Qual è il solito approccio per risolverlo?

Dimentica i puntatori a funzione e pensa agli oggetti. Ogni nodo nell'albero del comportamento (BT da questo punto in poi) corrisponderebbe idealmente a un oggetto nel codice. Questi oggetti avranno un'interfaccia standard per permetterti di sistemarli come un albero e per attraversarli. Un set di puntatori a funzioni va bene per il comportamento ma non cattura affatto la struttura dell'albero.

Di conseguenza non ha senso inserire le implementazioni di BT Action nei componenti poiché molto probabilmente saranno coinvolti molti componenti per azione, vero?

Mi aspetto che le entità abbiano un singolo componente BehaviorTree che memorizza i dati rilevanti per il BT di quell'entità. L'esecuzione di BT viene eseguita dal componente BT o dal sottosistema BT in base alla modalità di gestione dei componenti nel sistema. Come per quasi tutto ciò che utilizza i componenti, dovranno fare riferimento ad altri componenti per completare il lavoro, ma quegli altri componenti non dovranno sapere nulla dei BT.

Le diverse azioni disponibili verrebbero codificate al livello più semplice nei vari oggetti nodo BT. Dovrebbero essere in grado di far agire l'entità pertinente manipolando i componenti secondo necessità, ad es. accedere al componente di movimento per spostarsi.


Paragrafo n. 1: Sì, lo stesso BT sarà un oggetto (come ho detto come la versione di AiGameDev). Stavo solo pensando ai funzionali delle azioni stesse, ma il tuo paragrafo 2 l'ha cambiato. Per qualche ragione questo approccio davvero semplice non mi è mai venuto in mente (Entity con la propria istanza di membro BT). Probabilmente a causa dell'intero nuovo componente, non pensavo più dritto e semplice, quindi stavo cercando un modo per mescolare componenti con roba BT, ma non è necessario.
Philip Allgaier,

La cosa principale su cui mi ero perso in precedenza, era come collegare l'azione con l'entità. Ora è chiaro: le azioni conoscono l'entità attraverso il suo albero che a sua volta conosce l'entità a cui appartiene.
Philip Allgaier,

@Philip Allgaier Sono curioso, come sei arrivato a creare il nodo BT? Lo hai creato come 1 nodo comportamento = 1 entità (che sarebbe un sacco di entità per 1 oggetto di gioco), o hai creato un nodo come una classe normale (non correlato a ECS) o hai usato altri approcci? Grazie!
cppBeginner,
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.