Para mi proyecto actual, implementé un sistema basado en componentes / entidades , básicamente siguiendo la mayoría de las mejores prácticas que hay en esta área bastante indefinida .
Entonces obtuve Entidades (ligeramente extendidas) , que son básicamente una int
ID, un Nombre legible por humanos, un std::map
componente y un long
"indicador de tipo" que se usa para mostrar qué componentes están presentes (tengo una potencia de dos enum
para todos los componentes tipos y cada vez que se agrega un componente a la Entidad, automáticamente modifico ese largo mediante operaciones bit a bit, comparo esta respuesta ).
Luego están los componentes , también bastante simples: int
ID, enum
como tipo de componente, puntero de entidad principal y una std::map
de todas las propiedades que posee este componente.
Por último, algunos sistemas / gerentes que manejan el procesamiento lógico real. Primero verifican si la Entidad procesada actualmente tiene un long
"indicador de tipo" coincidente = todos los componentes necesarios para ese sistema están presentes. Luego accede a algunas propiedades si es necesario y llama directamente a algunas funciones en el componente respectivo o envía algunos mensajes (a través de un despachador de mensajes).
En pocas palabras: hasta aquí, un sistema basado en componentes / entidades basado en eventos bastante estándar combinado con un enfoque basado en datos (comparar, los componentes no tienen variables de datos codificadas, sino un mapa genérico, como (algunos) componentes / los arquetipos de componentes se leerán más tarde de los archivos con la opción de agregar datos adicionales, que no forman parte del código de componente real.
Ahora me gustaría también introducir Behavior Trees (basado en AiGameDev BTSK ) en ese proyecto, pero no estoy seguro de si deberían vincularse a los componentes ya existentes o cómo integrar esos diseños en general y cómo.
Varias ideas relacionadas / puntos / preguntas vienen a la mente:
Mis BT se leerán de los archivos (nuevamente). Actualmente tengo dificultades para ver cómo, sin embargo, haría la mejor conexión entre un
BT Action
árbol y la codificación real en mi aplicación. ¿Debo construir algún tipo de mapa entre los nombres de acción utilizados en los archivos BT y un puntero de función a la implementación lógica real? ¿Cuál es el enfoque habitual para resolver eso?Supongo que tendré que crear BT para todos mis diferentes
Entity
tipos (por lo que para cada combinación de componentes de lógica de juego / IA relevante como lo indica mi "indicador de tipo" largo mencionado varias veces). Como resultado, no tiene sentido incluir lasBT Action
implementaciones en los componentes, ya que lo más probable es que intervengan muchos componentes por acción, ¿verdad?Entonces, ¿la
BT Action
lógica debería estar en uno / múltiples sistemas separados (a cuyos métodos apunta el mapa de la idea # 1)? Luego, el sistema verificará, según milong
"indicador de tipo", si elEntity
BT para el que se verifica actualmente y si se le dijo que ejecutara una determinada acción (= método en el sistema) realmente tiene permitido hacerlo (= tiene los componentes necesarios). Pero entonces, si no (porque, por ejemplo, el creador de BT pasó por alto una situación específica, donde un componente necesario podría no estar conectado a la Entidad en tiempo de ejecución), no pasaría nada.
Preguntas:
- ¿Existen conceptos probados para ese tipo de integración?
- ¿Cuál es su opinión sobre mis 3 puntos anteriores?
- ¿Alguna otra cosa que se me ocurra, también con respecto a mi diseño basado en componentes / entidades en general?
fuente
Respuestas:
Olvídate de los punteros de función y piensa en los objetos. Cada nodo en el árbol de comportamiento (BT desde este punto en adelante) correspondería idealmente a un objeto en su código. Esos objetos tendrán una interfaz estándar que le permitirá organizarlos como un árbol y atravesarlos. Un conjunto de punteros de función está bien para el comportamiento, pero no captura la estructura de su árbol en absoluto.
Esperaría que las entidades tengan un solo componente BehaviorTree que almacena los datos relevantes para el BT de esa entidad. La ejecución del BT la realiza el Componente BT o el Subsistema BT, dependiendo de cómo maneje los componentes en su sistema. Al igual que con casi cualquier cosa que use componentes, deberán referirse a otros componentes para hacer el trabajo, pero esos otros componentes no tendrán que saber nada sobre los BT.
Las diferentes acciones disponibles se codificarían, en el nivel más simple, en los diversos objetos del nodo BT. Deben poder hacer que la entidad relevante actúe manipulando los componentes según sea necesario, por ejemplo. accediendo al componente de movimiento para moverse.
fuente