Detección de colisión y respuesta en un sistema de entidad

12

Más diversión con un ES ...

Actualmente, tengo algunos sistemas:

  • Renderizador (atributo renderizable, atributo Transformar)
  • Movimiento (atributo móvil, atributo de transformación, atributo renderizable [para cuadros delimitadores, etc.])
  • Entrada (atributo InputReceiver)
  • etc.

Estoy agregando detección de colisión. Lo primero que pensé fue agregar un nuevo sistema que realizara la colisión. Tiene sentido para mí mantener esta aislado del Motionsistema, ya que no todas las cosas que se mueven o están animadas necesariamente participar en la detección de colisiones - cámaras, niebla, etc - pero parece que Collisiony Motionson interdependientes.

Cuando Motionmueve una entidad, la transformación debe validarse Collisiony el movimiento puede cancelarse o ajustarse (rebotar, detenerse en una pared, etc.).

Una alternativa sería crear un atributo Collidable que mantenga una referencia a un objeto de colisión: kd-tree, octree, etc., que se comparte entre entidades que pueden colisionar entre sí. El Motionsistema sería a continuación, comprobar para ese atributo, y lo utilizan para comprobar o ajustar el movimiento.

Desde la perspectiva del código, esa es una solución aceptable. Sin embargo, desde el punto de vista de la arquitectura ECS, parece que está empujando la lógica al Motionsistema que no se aplica a todas las entidades que tienen un Movableatributo.

También podría almacenar un vector de movimiento en el Movableatributo, y hacer que el Collidersistema se ajuste Transformsegún sea necesario, pero eso implicará duplicar la funcionalidad entre Motiony Collider, o una devolución de llamada de Collidera Motioncon algunos datos sobre la ubicación de la colisión y los datos de superficie para rebote / reflexión, etc. .

Esto puede caer bajo el encabezado de "pirateo de casos especiales", pero me gustaría obtener información de aquellos que han manejado esto antes sin crear una tonelada de código de caso de borde.

La pregunta ¿Cuál es una buena manera de evitar un acoplamiento estrecho entre los sistemas de movimiento y colisión cuando parece que requieren conocimiento mutuo?

3Dave
fuente
1
¿Cuál es la pregunta?
jcora
@Bane, ¿cuál es un buen lugar para poner la lógica de detección de colisión, manteniendo la colisión + movimiento lo más separada posible y manteniendo al mínimo las interdependencias entre sistemas? Mi publicación fue un poco
divagada
1
Genial, ahora pon eso en tu pregunta, en negrita . :)
jcora

Respuestas:

7

Lo estás pensando demasiado. En mi motor, que también usa un sistema de entidad-componente, cada uno GameObjectpuede tener un puntero a un ModuleCollision.

Qué sucede cuando se actualiza el juego:

  • Scene actualiza todos los objetos que contiene. Llama a la Updatefunción para cada uno GameObject.
  • Dentro de la Updatefunción, cada uno GameObject solo actualiza su velocidad y dirección, no su posición.
  • GameObjectcarga su posición actual, velocidad y dirección ModuleCollision, si hay una disponible.
  • La escena verifica las colisiones sobre una ModuleCollisionbase
  • Scene llama a la UpdatePostfunción en cada uno GameObject. Si el objeto tiene un módulo de colisión, obtiene la posición, velocidad y dirección actualizadas del módulo de colisión. La posición se actualiza con la velocidad y la dirección.
  • El GameObjectconstruye una matriz final de 3x3 fuera de su posición y rumbo.

Sí, hay alguna duplicación de estado, pero está bien. Hacer el manejo de colisiones en una ModuleCollisiones la mejor manera de hacerlo, porque de lo contrario tendría que verificar cada una GameObjectpara ver si tiene una ModuleCollisionmanija.

caballero666
fuente
2
Entonces, en lugar de preocuparse por la posición de retroceso en caso de una colisión, ¿está dividiendo la velocidad / aceleración de la traducción, alterando las basadas en cualquier colisión que se detecte, y luego esos cambios se propagan en una segunda actualización especializada dentro del mismo marco? Parece bastante limpio. Gracias.
3Dave
3

Lo haría así ...

Tener tres sistemas:

  1. Sistema de movimiento
  2. Sistema de aceleración
  3. Sistema de colisión

El sistema de movimiento aplica velocidades a las posiciones. El sistema de aceleración aplica fuerzas a las velocidades. El sistema de colisión detecta colisiones y aplica las fuerzas en las direcciones correctas o, si desea colisiones crudas, altera directamente las velocidades.

Por ejemplo, puede calcular el ángulo entre las colisiones usando atan2 , y luego usarlo para aplicar las fuerzas / velocidades correctas a los cuerpos.

Haga que el sistema de detección de colisión transmita mensajes si es necesario también.

jcora
fuente