Votre préoccupation, exprimée dans le commentaire de la première réponse, est valable, mais la mauvaise nouvelle est qu'il n'y a pas d'astuce simple pour la contourner. Ce que vous devez rechercher s'appelle détection continue des collisions avec une version simplifiée décrite dans mon réponse sur un sujet assez similaire :
En gros, pour chaque objet en mouvement dans votre scène, vous devez calculer le moment de la prochaine collision dans la fraction de l'image 0<t0<1
, puis avancer les positions jusqu'à cet instant t0 dans le cadre, mettre à jour les les vitesses dues à la collision et passer à la collision suivante. t0<t1<1
jusqu'à ce que vous atteigniez le temps de tn=1
(fin du cadre), en s'assurant que que vous ne restez pas bloqué au milieu de l'image à cause de l'arrondi des calculs. calcul ou d'objets "en coin". Pour les collisionneurs sphériques, cela est généralement effectué en utilisant capsule contre capsule (pour les paires d'objets) intersection et capsule ou boîte pour les frontières.
Contrairement au moteur simple de la réponse à laquelle je me réfère, Unity a une détection continue des collisions . Vous pouvez donc activer les collisions continues et la dynamique continue, ce qui est très coûteux en termes de calcul.
Vous pouvez également essayer d'utiliser RigidBody.SweepTest qui renvoie les informations sur les collisions les plus proches. Remarquez que même s'il y a aussi RigidBody.SweepTestAll ça n'aide pas beaucoup. Non seulement parce qu'elle ne renvoie que les 128 premières collisions, mais aussi parce qu'elle ne les traite pas puisqu'il n'y a pas de réflexion. Pour un comportement physiquement correct, vous devez faire ce qui est décrit ci-dessus - avancer le temps jusqu'à la première collision et mettre à jour les vélocités. Soit avec le moteur physique, soit par vous-même. C'est très coûteux et peu de jeux le font, même en trichant en utilisant des objets simplifiés (les sphères sont les moins chères car deux sphères balayées sont deux capsules et leur intersection est un calcul relativement bon marché), mais le nombre d'étapes, surtout dans le cas "coincé" où les objets n'ont nulle part où aller et par conséquent sont constamment en collision pourrait être très importante et de tels cas se produisent plus souvent qu'on ne le pense.
Pour les objets complexes, il est peu probable que vous puissiez faire mieux que SweepTest, à moins que vous ne le déclenchiez sur la base de primitives plus simples, telles que Physics.BoxCast
o Physics.SphereCast
. Encore une fois, même s'il y a Physics.BoxCastAll
y Physics.SphereCastAll
elles ne sont pas particulièrement utiles car seule la première collision est garantie. Ces xxxCastAll sont les fonctions que vous avez écrites et que vous recherchiez, alors essayez-les, elles pourraient fonctionner suffisamment bien pour votre cas d'utilisation.