2015-07-23 1 views
3

J'ai lutté avec ce que je pense devrait être un problème très simple:Calculer l'angle cible en fonction de l'angle actuel et de la position cible?

Diagram of the problem. Je connais l'angle de cap actuel (disons 15 degrés), et étant donné une transformation de gameObject cible, je veux calculer l'angle que je devrais tourner pour faire face à la cible. Dans l'exemple ci-dessus, je veux calculer dis 335ish deg.

Notez que j'ai besoin de calculer la cible angle, j'ai une autre classe qui, compte tenu de l'angle, prend soin de tourner le cap à l'angle désiré. Je suis conscient du Transform.LookAt() et d'autres fonctions similaires, ils ne s'appliquent pas dans cette situation parce que les raisons (dans l'autre classe je calcule essentiellement un quaternion d'Euler et Lerp jusqu'à ce que j'atteigne l'angle cible, en raison des contraintes du projet , Transform.LookAt() ne fonctionne pas).

Dans la première approche, j'ai essayé le calcul angle thêta avec le produit Dot de Vector3.forward et le vecteur de direction, n'a pas droit tout à fait de travail (soit mis en rotation pour toujours ou dans la mauvaise direction)

Diagram of the problem

targetAngle = Vector3.Angle(Vector3.forward, (target pos - current pos).normalized); 

Je pensais que peut-être si je pouvais calculer le vecteur de direction de cap actuel, je pouvais prendre le produit Dot de cela et la direction cible vecteur pour obtenir l'angle thêta, puis utilisez thêta et l'angle actuel pour déterminer la cible angle (360 - thêta ou somethi ng?) pour obtenir l'angle que je veux faire pivoter. Chose est, je n'ai que l'angle actuel et la position actuelle, je ne comprends pas comment calculer le vecteur de direction de cap actuel à partir de cette info. Dois-je simplement ajouter une constante arbitraire à la valeur Z de la position actuelle et soustraire de celle-ci la position actuelle, pour obtenir un vecteur dir? Semble hacky et comme ça ne devrait pas fonctionner.

Diagram of the problem

Toutes les idées sont les bienvenues.

Modifier: Informations additionnelles

Le code d'orientation/u/Asad Interrogés sur:

// Calculate the target Quat to rotate all children by 
    Quaternion targ = Quaternion.Euler(0, 0, targetAngleHeading); 
    // Calculate the Linear interpolation to apply to all children 
    Quaternion lerp = Quaternion.Lerp(children[0].transform.localRotation, targ, Time.deltaTime * speedHeading_dps); 

    foreach (GameObject c in children) 
    { 
     // Apply lerp calcualted above to all children 
     c.transform.localRotation = lerp; 
    } 
    // Update the current heading angle 1st child's local z angle 
    currentAngleHeading = turrets[0].transform.localEulerAngles.z; 

Puis, en FixedUpdate() J'ai:

if (currentAngleHeading != targetAngleHeading) 
    { 
     DesiredHeading(); 
    } 
+0

Est-ce que c'est en 2D? Sinon, vous avez besoin d'un vecteur unitaire pour indiquer votre relèvement actuel, pas un angle scalaire de 15 deg. –

+0

En outre, il serait utile si vous avez montré ce que votre code fait avec l'angle que vous calculez. Vous calculez correctement l'angle entre '(0, 0, 1)' et l'en-tête désiré. Êtes-vous sûr que votre code de rotation interprète aussi l'angle fourni par rapport à '(0, 0, 1)'? –

+0

Le commentaire "* n'a pas vraiment fonctionné correctement (soit tourné à jamais ou dans la mauvaise direction) *", ainsi que la preuve de vos diagrammes, suggère fortement que vous n'avez pas fait attention à vos signes. Les mathématiques que vous décrivez doivent être à la fois correctes et presque triviales à mettre en œuvre; à propos de la seule mince ** peut ** mal faire est de mélanger vos signes, –

Répondre

0

essayer cette place

vous pouvez directement prendre le vecteur dist vecteur ance de transform.position puis vector3.normalize (target.position - object.position)

c'est l'angle object'll veulent se déplacer

+0

Quoi? La normalisation de target.pos - object.pos est le vecteur de direction, ça ne me donne pas un angle ... – Murkantilism

1

Vous pouvez prendre votre transform de l'avant, et le vecteur de votre cible, et obtenir un angle ou une rotation de ceux-ci:

Vector3 vectorToTarget = target.transform.position - transform.position; 
Vector3 facingDirection = transform.forward; // just for clarity! 

float angleInDegrees = Vector3.Angle(facingDirection, vectorToTarget); 
Quaternion rotation = Quaternion.FromToRotation(facingDirection, vectorToTarget); 

Notez que la rotation est relative; c'est-à-dire que c'est la rotation dont vous avez besoin pour appliquer à partir de la position actuelle pour faire face à la cible.

+0

Bon, j'ai essayé ça sans la dernière étape de ma première approche. Je passe juste l'angle en degrés à mon autre classe qui gère ce que vous avez dit dans la dernière phrase, c'est-à-dire en appliquant la rotation de la position actuelle à l'angle donné en degrés. Je revisite cette approche, peut-être que j'ai fait une erreur idiote quelque part – Murkantilism

+0

Mmk donc après la ré-implémentation de la première approche, j'ai remarqué une petite erreur. J'utilisais Vector3.forward au lieu des enfants [0] .transform.forward. Après avoir corrigé cela, l'angle calculé était exactement le contraire de ce que je voulais, donc j'ai ajouté 180 et modulo'd par 360 pour obtenir le bon angle de rotation. Une autre chose, si je veux recalculer constamment ou au moins très régulièrement (par exemple tourner vers une cible en mouvement, ou tourner en mouvement, ou les deux) des suggestions sur ce que je dois changer ou faire? – Murkantilism

+0

Si vous souhaitez effectuer une rotation en douceur (c'est-à-dire sur un certain nombre d'images), vous devez regarder 'Quaternion.Lerp' ou' Quaternion.Slerp'. Tout cela est assez rapide pour que vous puissiez recalculer chaque image (en supposant que vous n'avez pas un million en cours d'exécution!). Si votre angle était opposé alors peut-être que vous calculiez la valeur 'vectorToTarget' en arrière. –