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?

Respuestas:
Lo estás pensando demasiado. En mi motor, que también usa un sistema de entidad-componente, cada uno
GameObjectpuede tener un puntero a unModuleCollision.Qué sucede cuando se actualiza el juego:
Updatefunción para cada unoGameObject.Updatefunción, cada unoGameObjectsolo actualiza su velocidad y dirección, no su posición.GameObjectcarga su posición actual, velocidad y direcciónModuleCollision, si hay una disponible.ModuleCollisionbaseUpdatePostfunción en cada unoGameObject. 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.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 unaGameObjectpara ver si tiene unaModuleCollisionmanija.fuente
Lo haría así ...
Tener tres sistemas:
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.
fuente