Détection de collision et réponse dans un système d'entité

12

Plus de plaisir avec un ES ...

Actuellement, j'ai quelques systèmes:

  • Renderer (attribut Renderable, attribut Transform)
  • Mouvement (attribut mobile, attribut de transformation, attribut de rendu [pour les boîtes englobantes, etc.])
  • Input (attribut InputReceiver)
  • etc.

J'ajoute la détection de collision. Ma première pensée a été d'ajouter un nouveau système qui effectue une collision. Il est logique pour moi de garder cela isolé du Motionsystème car toutes les choses qui bougent ou sont animées ne participent pas nécessairement à la détection de collision - caméras, brouillard, etc. - mais cela semble Collisionet Motionest interdépendant.

Lors du Motiondéplacement d'une entité, la transformation doit être validée Collisionet le mouvement annulé ou ajusté (rebond, arrêt sur un mur, etc.).

Une alternative serait de créer un attribut Collidable qui conserve une référence à un objet de collision - kd-tree, octree, etc. qui est partagé entre des entités qui peuvent entrer en collision les unes avec les autres. Le Motionsystème vérifierait alors cet attribut et l'utiliserait pour vérifier ou ajuster le mouvement.

Du point de vue du code, c'est une solution acceptable. Cependant, du point de vue de l'architecture ECS, il semble que cela pousse la logique dans le Motionsystème qui ne s'applique pas à toutes les entités qui ont un Movableattribut.

Je pourrais également stocker un vecteur de mouvement dans l' Movableattribut et faire Colliderajuster le système Transformselon les besoins, mais cela impliquera la duplication des fonctionnalités entre Motionet Collider, ou un rappel de Colliderà Motionavec quelques données sur l'emplacement de la collision et des données de surface pour le rebond / réflexion, etc. .

Cela peut tomber sous le titre de "piratage de cas spécial", mais j'aimerais obtenir des commentaires de ceux qui ont déjà géré cela sans créer une tonne de code de cas de pointe.

La question Quelle est la bonne façon d'éviter un couplage étroit entre les systèmes de mouvement et de collision quand il semble qu'ils nécessitent une connaissance mutuelle?

3Dave
la source
1
Quelle est la question?
jcora
@Bane ce qui est un bon endroit pour mettre la logique de détection de collision, en gardant la collision + le mouvement aussi séparée que possible, et en gardant les interdépendances entre les systèmes au minimum. Mon message était un peu
errant
1
Super, maintenant mettez cela dans votre question, en gras . :)
jcora

Réponses:

7

Vous y pensez trop. Dans mon moteur, qui utilise également un système de composants d'entité, chacun GameObjectpeut avoir un pointeur sur a ModuleCollision.

Que se passe-t-il lorsque le jeu est mis à jour:

  • La scène met à jour tous les objets qu'elle contient. Il appelle la Updatefonction pour chacun GameObject.
  • À l'intérieur de la Updatefonction, chacun GameObject ne met à jour que sa vitesse et sa direction, pas sa position.
  • GameObjecttélécharge sa position actuelle, sa vitesse et sa direction sur son ModuleCollision, le cas échéant.
  • La scène effectue une vérification de collision sur une ModuleCollisionbase.
  • La scène appelle la UpdatePostfonction sur chacun GameObject. Si l'objet possède un module de collision, il récupère la position, la vitesse et la direction mises à jour à partir du module de collision. La position est mise à jour avec la vitesse et la direction.
  • Le GameObjectconstruit une matrice 3x3 finale à partir de sa position et de son cap.

Oui, il y a une certaine duplication d'état, mais ça va. La gestion des collisions sur un ModuleCollisionest la meilleure façon de procéder, car sinon vous devriez vérifier chacun GameObjectpour voir s'il a une ModuleCollisionpoignée.

chevalier666
la source
2
Donc, plutôt que de vous soucier de la position de retour en arrière en cas de collision, vous divisez la vitesse / l'accélération de la traduction, en modifiant celles basées sur les collisions détectées, puis ces changements sont propagés dans une deuxième mise à jour spécialisée dans le même cadre? Semble assez propre. Merci.
3Dave
3

Je le ferais comme ça ...

Ont trois systèmes:

  1. Système de mouvement
  2. Système d'accélération
  3. Système de collision

Le système de mouvement applique des vitesses aux positions. Le système d'accélération applique des forces aux vitesses. Le système de collision détecte les collisions et applique les forces dans les bonnes directions ou, si vous voulez des collisions brutes, modifie directement les vitesses.

Par exemple, vous pouvez calculer l'angle entre les collisions en utilisant atan2 , puis l'utiliser pour appliquer les forces / vitesses correctes aux corps.

Demandez également au système de détection de collision de diffuser des messages si nécessaire.

jcora
la source