La physique dans un projet Unity utilisant le combat mobile comme exemple


La physique est devenue une partie intégrante de tout jeu moderne. Qu'il s'agisse d'une simple simulation tissulaire ou d'une physique à part entière du trafic. Les jeux mobiles ne font pas exception. Cependant, lors de la configuration de la physique pour eux, vous devez repenser aux limites associées aux performances relativement médiocres des appareils de génération plus ancienne pris en charge. Le principal artiste technique 3D Banzai, Roman Tersky, a expliqué comment son équipe a intégré la physique dans le gameplay du jeu de combat mobile Shadow Fight 3, quelles techniques ont été utilisées pour l'optimisation et comment il a réécrit la physique à partir de zéro pour les personnages afin d'atteindre son déterminisme complet dans le PVP synchrone.

Physique du solide




L'équipement des personnages de Shadow Fight 3 comporte de nombreux éléments soumis à une simulation physique, ce qui ajoute de la dynamique à ce qui se passe à l'écran. L'une des principales difficultés que nous avons rencontrées lors de la mise en place de la physique de ces éléments est le fait que les os auxquels ils sont attachés se trouvent à l'intérieur de la hiérarchie du squelette du personnage lui-même. En se déplaçant, ils répètent la transformation des os parents et ne reçoivent pas d'impulsion physiquement réaliste.

Détecteur d'os


La solution la plus simple était un décollement osseux. Après avoir initialisé tous les éléments d'équipement à l'aide d'un script, nous supprimons les os des éléments physiquement actifs de la hiérarchie du squelette du personnage et, à l'aide du composant Joint de personnage , créons une connexion avec l'os parent.



Cependant, nous avons été confrontés à une petite erreur résultant du rabattement fps: dans ce cas, un os soumis à une simulation physique, avec un léger retard, «rattrape» l'os auquel l'articulation est connectée. En règle générale, cette erreur est si insignifiante qu'elle peut être négligée. Pour d'autres cas, une solution alternative a été appliquée.

Fausse impulsion


Considérons cette solution en utilisant l'exemple d'un casque de maraudeur, dont la crête spartiate est soumise à une simulation physique. Nous avons divisé le peigne en 5 parties, chacune étant écorchée d'os différents. Dans les paramètres Joint de ces os, ils définissent des limites de rotation le long de l'axe souhaité et définissent le paramètre Twist Limit Spring , qui est responsable de l'effet de ressort.



Pour une simulation physiquement réaliste, les os de la crête ont été retirés de la hiérarchie des personnages, cependant, dans le cas du rabattement fps, par exemple sur un appareil faible, le maillage était moche étiré en raison du «rattrapage» des os.



Par conséquent, nous avons décidé de laisser les crêtes à l'intérieur de la hiérarchie des personnages et d'augmenter leur dynamisme en leur donnant une fausse impulsion. Pour ce faire, nous avions besoin dans chaque animation (à l'exception de la position de combat) de déterminer le moment où appliquer l'impulsion, ainsi que sa direction.

On pourrait lire le nombre d'images dans l'animation en cours, puis soustraire 15 à 20 images de cette valeur et appliquer une impulsion après la différence reçue. Cependant, nous avons réussi à éviter l'arithmétique inutile en reliant le moment de l'impulsion à la fin de l' intervalle d' animation ininterrompu .

Chaque animation (encore une fois, à l'exception de la position de combat) a une période préconfigurée pendant laquelle le joueur ne peut pas l'interrompre. Après cette période ou au moment de la réception de l'impact, l'intervalle ininterrompu met fin à son action, et à ce moment notre impulsion est déclenchée. Il suffisait de configurer des exceptions pour plusieurs animations.



Ainsi, l'impulsion est déclenchée plusieurs images avant la fin de chaque animation, selon nos besoins. Au moment de l'initialisation de l'impulsion, nous lisons les coordonnées dans lesquelles l'os se trouvait dans la trame précédente et actuelle, recevant son vecteur de mouvement. Sur cet axe, notre impulsion est appliquée.

Articles d'équipement


Afin d'optimiser, nous essayons d'utiliser le moins possible de collisionneurs lors de la simulation physique de divers éléments de l'équipement des personnages. Dans la plupart des cas, nous parvenons à le faire en manipulant uniquement les restrictions le long des axes dans les paramètres Joint des os pour lesquels la simulation est effectuée.



Dans certains cas (par exemple, avec des plaques métalliques), l'utilisation de collisionneurs est inévitable. Cependant, le principal fardeau n'est pas la présence même des collisionneurs, mais le calcul de leurs collisions. Un réglage fin de la matrice de collision des couches dans les paramètres du projet permet de minimiser cette charge. Pour de tels éléments, nous utilisons deux couches distinctes qui n'entrent en collision qu'entre elles, évitant ainsi les erreurs de calcul des collisions avec les collisionneurs d'autres couches (armes, sols, murs, etc.)



Clone physique


Shadow Fight 3 possède plusieurs types d'armes pour lesquelles la simulation physique est utilisée en dehors des animations d'attaque. Pour le moment, c'est un couteau sur une chaîne, un kusarigama, un nunchaku et un fléau. Pour les raisons décrites ci-dessus, nous avons décidé de supprimer les os de l'arme de la hiérarchie des personnages en dehors des animations d'attaque et de les restituer lorsqu'une simulation physique n'est pas requise. En manipulant le paramètre Is Kinematic dans le composant Rigidbody des os, selon la situation, nous activons et désactivons la physique pour eux.

Cependant, lors de l'utilisation de Kusarigama et d'un couteau sur la chaîne, nous avons rencontré une charge accrue sur les appareils faibles et obtenu un tirage fps. Le problème est survenu précisément lorsque les os sont revenus dans la hiérarchie du personnage et que la simulation physique a été désactivée pour eux. Cela est dû au fait que la modification des transformations d'os parent dans la hiérarchie du squelette met à rude épreuve le moteur physique pour chaque os fille sur lequel se trouve un composant Rigidbody , même si le paramètre Is Kinematic est actif. Et plus la hiérarchie est longue, plus la charge est importante.



La solution était de créer un clone physique. Considérez ceci avec un exemple de couteau sur une chaîne.

Pendant le chargement de bataille, 2 squelettes sont initialisés pour lui: le principal, qui est situé à l'intérieur de la hiérarchie du personnage, et son clone physique. Il n'y a pas de composant Rigidbody dans les os du squelette principal; seules les pistes d'animation affectent leur transformation. Les os du second ont des connexions accordées (Articulations) et un composant Rigidbody avec le paramètre actif Is Kinematic.

Alors que la transformation des os du squelette principal est affectée par la piste d'animation, par exemple, lors d'un hit, le paramètre Is Kinematic dans le composant Rigidbody des os du clone physique reste actif. Les os ne sont pas transformés et ne sont pas soumis à une simulation physique. Pendant la dernière image de l'animation, les transformations osseuses des deux squelettes sont synchronisées. Un clone physique lit la position et la rotation des os du squelette principal et définit ses mêmes paramètres exacts. Is Kinematic est alors désactivé et les os du clone physique sont simulés. De plus, jusqu'au début de la prochaine animation d'attaque, déjà le squelette principal, chaque image lit les transformations des os du clone physique, qui à ce moment se déplacent en physique, et définit ces paramètres sur leurs os. Cette approche a considérablement réduit la charge du moteur physique et amélioré les performances sur les appareils faibles.



Simulation tissulaire


Lors de la configuration de la simulation tissulaire dans le cadre des performances des appareils mobiles, la principale limitation est l'utilisation de collisions tissulaires avec des collisionneurs. Une alternative moins coûteuse consiste à affiner la pénétration de surface pour les tissus. Étant donné que dans notre jeu, il y a beaucoup d'animations et diverses poses de personnages, une liste des plus «dangereuses» a été compilée, sur laquelle tous les tissus ont été vérifiés pour la pénétration à travers d'autres parties du corps.



Nous avons également utilisé une simulation de tissu pour créer l'effet de flamme FX sur les armes et sur la tête du boss Shadow Mind. Dans les paramètres de tissu de ces éléments, nous avons désactivé l'influence de la gravité et défini les valeurs d'accélération le long de l'axe Y: constantes, de sorte que la flamme se déplace vers le haut, et de manière aléatoire, pour l'effet de flottement. Pour que lors du déplacement, il n'y ait pas de distorsion prononcée de la géométrie, nous définissons l'augmentation de la valeur de la résistance ( amortissement ). Ainsi, nous avons obtenu un effet de flamme assez réaliste et bon marché en termes de performances.





Physique déterministe pour le PvP synchrone


Au moment de la mort et dans certaines situations, lors de la frappe de personnages dans Shadow Fight 3, une simulation de la physique est activée. Pendant longtemps, la physique du solide du stock Unity a été utilisée pour cela. Cependant, lors de l'introduction du PVP synchrone dans le projet, il a dû être abandonné au profit de son propre développement.

Le PVP synchrone implique la même simulation d'un jeu sur deux clients. L'animation ne pose aucun problème, car tout a été calculé à l'avance, tandis que certains problèmes surviennent avec la physique.

Le fait est que les calculs en virgule flottante, qui sont utilisés à l'intérieur de la physique dans Unity, fonctionnent différemment sur les processeurs de différents fabricants. À cet égard, pendant le jeu, des erreurs dans la position des personnages s'accumulent - sur un client, le personnage est situé différemment de l'autre. Et si en dehors de la physique, cet écart peut être facilement corrigé en synchronisant périodiquement la position sur la base des indicateurs d'un des clients, puis lors de l'initialisation de la physique, en raison de l'erreur de démarrage de la position, la simulation physique se développe différemment sur deux clients.

En conséquence, le personnage est significativement à différents endroits et dans différentes positions. Après une telle divergence, tôt ou tard se produira une situation dans laquelle des attaques seront enregistrées sur un client et non sur l'autre.

La solution la plus simple, à première vue, consiste à prendre la position du personnage sur un client et à la transférer sur un autre tout en les synchronisant lors d'une simulation physique. Mais le regdoll du personnage est une longue hiérarchie d'os avec un grand nombre de solides indépendants séparés (membres, tête), pour la synchronisation correcte de la position dont vous avez besoin de transférer une grande quantité de données dans un court laps de temps. Cette option s'est avérée trop «chère», nous avons donc décidé d'écrire notre propre physique, qui serait déterministe. De sorte que nous pouvons être sûrs que sur n'importe quel client les états physiques des caractères coïncident, quel que soit le processeur sur lequel les calculs sont effectués.



Alors, quelle est notre regdoll? Le corps est constitué de nœuds, qui sont des points matériels. Ils n'ont pas d'orientation, mais il y a une position et une masse, et entre eux des liens de rigidité réglable sont réalisés. Un groupe de ces nœuds est attaché à chaque os à l'intérieur du squelette du personnage. Cette architecture implique l'absence de collisions internes et de limitations dans les articulations, et les collisions externes et les frottements sont implémentés au niveau du nœud. Lorsque les nœuds se déplacent dans l'espace, la gravité, les forces externes et l'inertie sont prises en compte.

Entre les nœuds, il existe deux types de connexions: les côtes rigides (bleues) et les muscles élastiques (rouges). Les côtes jouent le rôle d'os, forçant les nœuds à une certaine distance les uns des autres et les empêchant de se disperser dans des directions différentes. Les muscles de n'importe quelle position de départ forment une certaine pose à partir des nœuds, en les rapprochant si la distance entre eux est supérieure à la valeur cible et en les écartant si elle est inférieure.



Jetez un œil «sous le capot» et voyez comment cela fonctionne. Tout d'abord, nous permettons aux nœuds de se déplacer librement, puis d'ajuster itérativement les liens afin qu'ils retrouvent leurs caractéristiques cibles. Pour une itération de l'ajustement musculaire, deux itérations de l'ajustement des côtes sont nécessaires. En rendant les côtes plus rigides, nous pouvons être sûrs que les connexions des côtes ne se briseront pas après que les muscles soient exposés aux nœuds.



En conséquence, plus les nœuds parviennent à se déplacer au stade de la libre circulation, plus les coûts de calcul doivent être investis pour restaurer les côtes et les muscles. Pour minimiser ces coûts et les risques de rupture structurelle, nous avons décidé de décomposer le processus itératif en plusieurs étapes. C'est-à-dire que dans une trame plusieurs fois la libre circulation des nœuds et leur correction se produisent. En une étape, les nœuds parviennent à se déplacer beaucoup moins, et les ajuster devient beaucoup plus facile. Ainsi, nous économisons sérieusement sur le nombre d'itérations nécessaires pour ajuster les côtes et les muscles.



L'ensemble des longueurs musculaires détermine la pose cible, que le personnage recherche depuis n'importe quelle position après la transition vers une simulation physique. Pour éviter les transitions trop brusques et les perturbations structurelles, nous avons ajouté l'interpolation pos. Au moment d'entrer en physique, nous prenons la pose actuelle du personnage et en faisons la cible, puis pendant cinquante images, nous l'interpolons à la pose cible prédéfinie, obtenant une transition en douceur.



Le principal problème que nous avons rencontré lors de l'utilisation de notre physique est la torsion périodique des membres, principalement des bras. Cela est dû au fait qu'au moment de la transition vers la physique, le personnage peut être dans une position loin de la cible, à laquelle ses muscles se resserrent. Pour minimiser et, à l'avenir, éviter complètement de telles situations, un certain nombre de mesures ont été appliquées. Tout d'abord, nous avons mis en place plusieurs poses cibles auxquelles les muscles peuvent resserrer les nœuds. Au moment où nous entrons dans la physique, nous prenons la pose actuelle, regardons laquelle des cibles prédéfinies est la plus proche et resserrons les nœuds.



Initialement, lors du passage à la physique, les muscles ont poussé rigidement les nœuds, les amenant à la position souhaitée. Souvent, la netteté de cette répulsion a également conduit au fait que les extrémités se tordaient fortement. Nous avons ajouté une augmentation douce de la force musculaire, ce qui a grandement amélioré la situation. Pendant les deux premières images après le début de la simulation physique, la force musculaire reste à son maximum pour stabiliser les nœuds après leur avoir appliqué une impulsion. Ensuite, les muscles se détendent, leur force devient 55%, puis sur 120 images, la force augmente progressivement jusqu'à 100%.



La dernière étape a été l'ajout de deux nœuds stabilisateurs: l'avant au niveau de la poitrine et le dos au niveau des jambes. Ces nœuds ont des connexions nerveuses avec des nœuds fixes de la poitrine et du bassin, respectivement, et des nœuds instables se resserrent avec les muscles. Les nœuds stabilisateurs ont une faible valeur de masse et n'ont pas de collision avec le sol, contrairement aux autres nœuds.



Dans le gif ci-dessous, vous voyez le résultat: nous avons obtenu une physique complètement déterministe construite sur des calculs entiers qui fonctionne de manière stable à 60 images par seconde, même sur les appareils les plus faibles que nous prenons en charge.



Suivez Banzai Games sur les réseaux sociaux: Facebook , Vkontakte , Instagram , LinkedIn

L'équipe de Banzai Games a besoin d'un spécialiste VFX expérimenté. En savoir plus sur l'offre d'emploi ici .

Source: https://habr.com/ru/post/fr480108/


All Articles