2015-04-19 3 views
0

Je suis une période très difficile car je ne peux pas comprendre le problème:Distance changement de magnitude entre un objet et une planète en orbite autour de Unity 3D

Je suis en train de faire un mouvement d'objet sur une orbite circulaire autour une planète en utilisant une formule trouvée sur wikipedia, des façons voici mon code:

public void circularOrbit(Collider2D col,float planetMass){ 

    mPlanet = planetMass; 
    dist = new Vector2 (col.gameObject.transform.position.x - gameObject.transform.position.x, col.gameObject.transform.position.y - gameObject.transform.position.y); 
    r = dist.magnitude; 
    print (r); 
    tdist = new Vector2 (-dist.y, dist.x).normalized; // 2D vector prependicular to the dist vector . 
    float speed = Mathf.Sqrt (G*mPlanet/r) ; // Calculate the velocity . 
    print (speed); 
    rigidbody2D.velocity = tdist * speed; 


} 

collisionneur 2D col est le collisionneur de l'orbite de la planète, quand mon objet a frappé ce collisionneur il commence à se déplacer sur une voie circulaire selon les calculs que j'ai faits.

Tout se passe dans une mise à jour fixe avec quelques conditions (pas vraiment liées à ce sujet), le problème auquel je suis confronté est que mes grandeurs de distance ne cessent de changer everyframe, où j'en ai besoin pour rester le même!

Cela cause un problème puisque la vitesse va changer et pour d'autres scripts j'ai besoin de le réparer.

Voici quelques valeurs de r la magnitude de distance:

4,602833

4,602901

4,603098

Le changement est très faible, mais il affecte mon jeu trop .

Alors s'il vous plaît expliquer pourquoi c'est hapenning?

Merci.

+0

"Alors s'il vous plaît expliquer pourquoi c'est hapenning?" - Il y a beaucoup de calculs en virgule flottante sur votre code et la précision en virgule flottante est le diable ici je pense. Une autre chose peut-être l'impact de collision qui causent la distance de vos gameobjects change très légèrement. "Contournement" - Peut-être que vous pouvez utiliser Mathf.Round pour restreindre la valeur décimale à virgule flottante. "Solution peut-être" - En cas de collision avec le collisionneur de l'orbite de la planète, vérifiez une seule fois, prenez la valeur de r et faites l'orbite séparément. Pas besoin de vérifier la distance à chaque image ou FixedUpdate() etc. car les fonctions mathématiques sont lourdes. –

+0

Eh bien, en fait j'essaie de le faire mais, il y a un autre problème: l'objet entre en orbite un petit moment, puis il sort de l'orbite. Aussi ma logique est que quand l'objet heurte le collisionneur de planètes isOrbit devient vrai, puis dans le FixedUpdate je vérifie cette variable booléenne et si c'est vrai, j'appelle cette fonction, j'ai fait tous les calculs dist et r sur OnTriggerEnter2D, ces variables sont global donc ils sont utilisés directement par la fonction circularOrbit. – DeltaWeb

+0

Les moteurs de physique ne sont pas entièrement déterministes et ont une précision limitée. Comment une variation de ~ 0,0003 unités peut-elle casser votre jeu? Vous pouvez prendre le contrôle de l'objet directement, vous pouvez ajuster les paramètres physiques, ou vous pouvez retravailler un peu votre conception pour accommoder cette variation. – rutter

Répondre

0

Le moteur physique effectue ses mises à jour sur les mises à jour fixes. Entre ces mises à jour, la gravité n'agit pas sur l'objet. Ainsi, il se déplace dans un segment de droite qui commence tangent au cercle que vous voulez, mais à la fin de la période de mise à jour fixe, la distance a légèrement augmenté puisque le segment de ligne n'est pas le même que le cercle. Le résultat est que vous pourriez voir des erreurs beaucoup plus grandes que les erreurs d'arrondi.

Cette erreur est linéaire. Si vous avez deux fois plus de mises à jour ou réduisez la vitesse et la force de gravité d'un facteur deux, les erreurs sur chaque étape vont diminuer d'un facteur quatre, mais comme vous avez deux fois plus de mises à jour par orbite, la distance supplémentaire par orbite diminuerait d'un facteur de deux. Si vous avez une simulation compliquée avec des objets se déplaçant dans des ellipses et plusieurs sources de gravité significatives, alors je suggère d'utiliser une méthode comme leapfrog integration, qui économise l'énergie, ou une méthode de Runge-Kutta d'ordre élevé, qui est typiquement si précise que vous ne remarquerez pas les erreurs. Cependant, vous êtes déjà en train d'imposer une orbite circulaire au lieu de laisser le moteur physique calculer l'orbite. Donc, remplacez simplement les calculs du moteur physique, et forcez l'objet à être dans l'endroit le long de l'orbite que vous savez qu'il devrait être. Une façon de faire est de faire tourner l'ancien déplacement du centre de la planète d'un angle qui est (Time.deltaTime/period) * 2pi radians. Ce n'est pas parfait parce qu'il y a des erreurs d'arrondi qui peuvent s'accumuler. Une autre possibilité consiste à garder une trace de l'emplacement d'origine et de l'heure d'origine, et de calculer l'angle modifié en fonction de la différence entre l'heure actuelle et l'heure d'origine.

Une autre méthode qui devrait fonctionner est de se souvenir de ce que le rayon est censé être, et de renormaliser le déplacement du centre de la planète pour avoir une magnitude égale au rayon mémorisé.

+0

Eh bien, je vous remercie pour votre réponse, je suis seulement un lycéen donc mes maths/physique sont limitées pour maintenant, je vois votre dernière solution très logique, puisque je peux obtenir le rayon de chaque orbite, ici mon code complet avec cette solution: http://pastebin.com/0GCDEL7F, le code est très facile à comprendre, mais maintenant j'ai un autre problème, ce qui est très bizarre: mon objet sort de l'orbite alors que le 'r' reste le même, il en va de même pour l'amplitude et la vitesse de la vélocité. Voici un gif expliquant mon problème actuel: http://giphy.com/gifs/3oEdv73oLD3BtcP5M4. – DeltaWeb

+0

Oui, cette réponse explique pourquoi vous voyez l'objet en spirale et comment vous pouvez le réparer. Je l'ai prévenu dans un commentaire après ma réponse à la dernière question. –