Can't get useable angle between two rotations on a fixed axis?

Hello I’ve been trying to use Quaternion.Angle to get the difference between two rotations (on a single axis) as float, but it won’t tell me which direction to rotate in. Does anyone know how to determine how far on a specified axis to rotate an object in a way that gives me the direction of rotation?

Thanks a lot if you can help. It’s driving me nuts that Quaternion.Angle doesn’t seem to do this!

The reason is that any two rotations are just not defined to be negative / positive.

You need a third rotation (or axis) along which to consider the other rotations.

For instance, this method:

takes two vectors and an axis vector.

I think you could change your stuff to use this. It would be something like

// however you got these...
Quaternion rotationA = ...
Quaternion rotationB = ...

// then do..
Vector3 vectorA = rotationA * Vector3.up;
Vector3 vectorB = rotationB * Vector3.up;

Vector3 axis = Vector3.forward;

// and finally
float signedAngle = Vector3.SignedAngle( vectorA, vectorB, axis);

Whatever you choose for Vector3.up should be as orthogonal as possible to your chosen axis.

Thanks you, I tried to implement it, but I’m not sure I understand the results I’m getting. I think the axis may be tilted somehow. Am I right in thinking the Vector3.forward would imply it is doing a barrel roll? The instructions say 180 to -180, but the result is -5.to 5, with the numbers changing semi-randomly around the stationary object that’s doing the tracking. Front is not 0 or 180.

Am I translating this correctly? Or should I not be using the object’s up and transform? I did try Vector3.up too, but it seems the same both. I’ve also tried flipping A and B

Vector3 vectorB = Quaternion.LookRotation(target - transform.position) * transform.up; // Target rotation
Vector3 vectorA = transform.rotation * transform.up; //object
float signedAngle = Vector3.SignedAngle(vectorA, vectorB, transform.up);

This is your local “up” on wherever this script is located… is that what you want??

Also, not 100% sure about what your LookRotation is there…

Might be best to start with a description of what you have and where you’re going with this. :slight_smile:

Would this be a problem? The code is for the AI of a turret that might be upside down. It needs to be able to judge if it can turn right or left, in a turn based system, regardless of which way up it is. The idea is that I get the rotation to the object, and then divide it by the number of moves it can make to get the weight of that move. I also need it for the AI to actually preform the move itself as the move system is identical for all entities in the game. It just has either a player control system or an AI on top.

The lookrotation is getting the rotation to turn to face a target. But I can’t actually use it directly. That would override the move system that’s already there and break the game.

Hmm… based on that description it does sound like transform.up is correct for the axis argument, assuming you have this script on the thing that actually rotates to be in that “up” orientation, and assuming the turret rotates left/right on its local “up” axis.

This is pure cheese, but what about a little bit of extra functionality so that your turret can iteratively check this:

  • simulate as if you actually turned left - measure degrees to goal
  • simulate as if you actually turned right - measure degrees to goal

Based on those two reading, choose the one that actually got you closer to the goal.

Super-cheese, but hey, cheese is good… cheese ships games out. :slight_smile:

Otherwise, truth it out with a few known good vectors, like known unit vectors that you feed into things and get out the answer in a little test script. It will work if you feed it the right stuff.

Yeah, it’s the AI controller script. Or it will be, when I can get relational info on targets like this.

I think I’ve worked it out. for some reason the top down angle is around transform.forward. I assumed it would be up. Well, thanks a lot. It’s working now. I’m probably going to have to credit you in the game at this point lol.

Okay,. I take it back, I’ve not worked it out. Somehow, without me modifying the code at all, it has started giving me unsigned angles - and I’ve no idea why, or how to stop it. It’s just giving me a flat number. Not positive or negative. My AI was working, and now it’s suddenly not - without me changing anything. I’m really confused. Any ideas?

Am I wrong to use the local transform for the target multiplication? It doesn’t seem to make a difference. I’m getting the angle correctly, except it’s always positive somehow. This is returning directly into a Debug btw, so this is all that’s affecting this.

 return Vector3.SignedAngle(transform.rotation * transform.forward, Quaternion.LookRotation(target - transform.position) *transform.forward, transform.forward);