Comment mettre en œuvre la «conscience» ennemie des unités?


12

J'utilise Unity3d pour développer un jeu prototype hybride RTS / TD. Quelle est la meilleure approche pour la «prise de conscience» entre les unités et leurs ennemis? Est-il sensé que chaque unité vérifie la distance de chaque ennemi et s'engage si à portée?

L'approche que je veux en ce moment est d'avoir une sphère de déclenchement sur chaque unité. Si un ennemi entre dans la détente, l'unité prend conscience de l'ennemi et commence la vérification de la distance. Cela évite-t-il des vérifications inutiles?

Quelle est la meilleure pratique ici?


Je dois ajouter que le nombre d'unités / d'ennemis va être dans l'échelle du commandant suprême
Phil

Réponses:


10

Examinez les hiérarchies de volumes englobantes (BVH). Ils sont le plus souvent utilisés dans la détection des collisions pour réduire le nombre de vérifications nécessaires lors du calcul des collisions ou dans le rendu pour effectuer un tri sélectif des objets. Puisque vous utilisez déjà des sphères, je suggérerais un arbre de sphère bien que d'autres volumes tels que les AABB puissent être plus efficaces. Je ne sais pas quel type de support Unity a pour des choses comme je ne l'ai jamais utilisé, mais il y a probablement quelque chose pour cela déjà dans la détection de collision ou le rendu de parties du moteur.

Fondamentalement, vous souhaitez regrouper les ennemis proches les uns des autres dans plusieurs sphères parentales. Lorsqu'une unité est déplacée, vous devriez vérifier que sa sphère de déclenchement est contre la sphère parent au lieu de vérifier chaque ennemi. Si la sphère de déclenchement croise la sphère parent, vous vérifieriez chaque ennemi à l'intérieur. Si ce n'est pas le cas, vous pouvez éliminer tous les ennemis qui s'y trouvent. Vous souhaitez configurer plusieurs niveaux de sphères en fonction d'une taille de sphère maximale ou du nombre d'ennemis pour chaque sphère et effectuer la vérification en fonction d'une sphère de niveau supérieur. Ensuite, il suffit de descendre l'arbre afin de vérifier chaque ennemi sans avoir à effectuer la vérification de distance pour chacun.

Étapes requises pour chaque image:

  1. Déplacer les ennemis
  2. Reconstruire / mettre à jour le BVH pour de nouvelles positions ennemies
  3. Déplacez les unités et vérifiez l'arborescence des sphères.

Cela peut réduire les vérifications nécessaires lorsqu'il y a beaucoup d'ennemis, mais les frais généraux de mise à jour et de stockage de l'arbre peuvent ne pas en valoir la peine lorsqu'il n'y en a pas beaucoup. Je ne suis pas familier avec Supreme Commander pour savoir ce que vous recherchez, donc je suppose que des «centaines». Vous devrez établir un profil dans différentes situations pour savoir si les frais généraux en valent la peine.


3
+1 cette approche sera la plus simple même si elle comportera quelques erreurs. OP peut vouloir implémenter cela, puis implémenter quelque chose comme un octree. De plus, dans la plupart des RTS, les unités réagissent avec un certain retard. En fait, la plupart des IA dans les jeux sont calculées de 10 à 30 images par seconde, où le jeu peut fonctionner à 30 à 60 images par seconde (les chiffres sont, bien sûr, des approximations).
Samaursa

Merci, c'était exactement ce dont j'avais besoin pour aller plus loin. Je vais chercher BVH et comment l'implémenter dans Unity. Poste très pédagogique et informatif! +1
Phil

Oh et consultez Supreme Commander si vous êtes sur RTS. C'est vraiment un très bon jeu, comme le sont tous les jeux de Chris Taylor.
Phil

7

Il n'est pas nécessaire d'implémenter BVH, car le moteur de collision d'Unity le fait déjà pour vous.

Il suffit de fixer un grand déclencheur englobant sphère à chaque unité (représentant sa gamme) et gérer la OnCollisionEnter()et OnCollisionExit()callbacks de garder une trace des ennemis sont à portée de chaque unité.

Notez que le cas qui vous intéresse est lorsqu'une autre unité entre en collision avec la sphère, et non lorsque la sphère d'une autre unité entre en collision avec la sphère.


1
Je pense que cela doit être voté au moins juste au-dessus de la réponse acceptée. La réponse acceptée est bonne pour étudier, mais cette réponse devrait être au sommet car c'est la manière la plus pratique.
Varaquilex

Je crois que tu veux dire OnTriggerEnter()et OnTriggerExit(), non?
Jibb Smart

1

Une autre solution qui évolue très bien et peut être utilisée pour une multitude d'autres choses est une carte d'influence. Générez un ensemble de tuiles de grille autour de l'unité pour numériser dans le rayon X. Scannez ces tuiles pour trouver un ennemi se tenant sur l'une d'elles. Si vous souhaitez obtenir les ennemis les plus proches, vous pouvez trier votre ensemble par distance.

Cela pourrait être la méthode la plus efficace, surtout si vous prévoyez de faire d'autres choses avec la carte d'influence comme le brouillard de guerre ou la recherche de chemin.

Voici une vidéo que j'ai réalisée expliquant le concept: https://www.youtube.com/watch?v=MEd6XV2Pecw .

Et voici une implémentation: https://www.youtube.com/watch?v=y_ewoxlZlgc

Je recommande de ne pas initialiser la collection d'unités de la tuile de grille au démarrage, mais uniquement lorsque la collection est nécessaire.

Alternativement, vous pouvez utiliser un tableau de longueur X si vous savez qu'il n'y aura jamais plus de X unités sur une tuile.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.