Je travaille sur un jeu où le joueur peut ramasser des objets en utilisant quelque chose comme un rayon tracteur et les transporter.
Attirer l'objet vers le centre du faisceau n'est pas difficile. Mais une fois que l'objet est suffisamment proche du centre, je dois le garder là pendant que le joueur bouge, ce qui me pose problème. Je peux penser à deux façons de le faire, et les deux ont des problèmes:
Mettez à jour la position de l'objet chaque fois que la position du joueur change, en le gardant centré sur la poutre.
Mettez à jour la vitesse de l'objet pour pointer directement vers le centre du faisceau, plus loin, plus la vitesse est élevée.
Le déplacement et la rotation fonctionnent très bien avec les deux approches, mais la physique est erronée lorsque l'objet transporté entre en collision avec d'autres objets:
Avec la première approche, la physique est complètement ignorée. L'objet transporté ne fait qu'éloigner quoi que ce soit. En effet, les changements de position ne sont censés être effectués que dans le cadre de la physique mondiale, en fonction de la vitesse.
Avec la deuxième approche, la physique se comporte essentiellement comme elle le devrait, mais réagit de manière excessive. Le problème est le suivant: afin de maintenir l'objet transporté au centre du faisceau même en rotation et en mouvement, je dois utiliser des valeurs de vitesse élevées. Ainsi, une fois que l'objet transporté en a touché un autre, la vitesse de la collision est beaucoup trop élevée.
Comment puis-je l'implémenter correctement? Ma meilleure supposition en ce moment est d'aller avec la deuxième approche et d'ajouter une manipulation spéciale pour les objets transportés à la physique du monde, en réduisant la vitesse à des valeurs sensées pour les collisions ou lorsque le joueur cesse de les transporter. Mais cela semble être une solution de contournement assez inélégante.
Edit: Ajout d'un pseudo code pour illustrer comment cela fonctionne en ce moment (ce serait la deuxième approche ci-dessus)
void attract_object(object, ticks) {
Vector distance = beam_center - object.center;
// If the object is not close to the beam center, attract it slowly
if (magnitude(distance) > 10) {
object.velocity += distance.normalized() * ticks * 0.1;
return;
}
// Here comes the part we're talking about. That magic 0.5 is just high enough
// that the object isn't lost while moving around. But it's still so high that
// other objects are repelled with way too much force.
object.velocity = distance * ticks * 0.5;
}
D'après ce que je vois, cela se produit lorsque l'objet transporté repousse un autre objet:
- L'objet transporté entre en collision avec un autre objet
- Les vitesses des objets sont distribuées correctement, donc l'objet transporté est éloigné du centre du faisceau dans le processus
- Le code ci-dessus provoque le retour de l'objet transporté au centre du faisceau, avec une telle vitesse qu'il y retournera rapidement
- Lorsque l'objet transporté recule vers le centre du faisceau, la moitié de sa vitesse élevée est transférée à l'autre objet, le repoussant violemment. Étant donné que la vitesse initiale de l'objet transporté semble être saine, je peux imaginer que les étapes 2 à 4 sont répétées plusieurs fois, créant une vitesse aussi élevée.
Cela semble être la cause. Je ne peux pas penser à une belle façon de le réparer :(