I’m trying to get an angle from an axis other then X, Y, and Z. So, for example, I want to get the angle around transform.forward in transform.rotation. How could I achieve this?
I’m not really clear on what you are trying to do here. Your diagram is not really clear. You have a circle labelled “quaternion”, a vector labelled “axis”, and another circle labelled “angle”.
Are you lookin for a single numerical result? Another Quaternion? A Vector? A circle?
What does the angle around a vector mean in a quaternion? An angle makes sense between two directional vectors, so which two vectors are you trying to find the angle between?
Sorry if i was not clear, I’m looking for a single numerical result. Something like Quaternion.AngleAxis, but instead of getting a quaternion rotated by angle around axis, I get the angle around a specified axis in a specified quaternion.
To get an angle you need two vectors. Maybe you’re asking about the angle between the “forward” vector for a given quaternion and some other vector? That would be something like this:
Quaternion someQuaternion;
Vector3 someVector;
// Get the "forward" direction for the quaternion
Vector3 quaternionForward = someQuaternion * Vector3.forward;
// Get the angle between that and our vector:
float angle = Vector3.Angle(quaternionForward, someVector);
If you want the angle around that forward vector like it’s an axis of rotation, you need to pick some arbitrary orthogonal direction to be “0 degrees” around that axis. Then you just calculate the angle between that “0 degree” direction and your vector:
Quaternion someQuaternion;
Vector3 someDirection;
// Let's use the local "right" direction of the quaternion as the zero angle vector:
Vector3 zeroAngleDirection = someQuaternion * Vector3.right;
// Now calculate the angle between to the two vectors:
float angle = Vector3.Angle(zeroAngleDirection, someDirection);
The localSpace trick is great for stuff like this. It let’s you pretend your “axis” like is along +z, convertng the point on that ring as if if were around +z. Assume p1 is some spot on that ring:
Vector3 axis = ...
Quaternion toLocal=Quaternion.Inverse(Quaternion.Lookrotation(axis));
// toLook*axis is now (0,0,z) -- pointing straight forward
Vector3 p2=toLocal*p1;
Now p2.z is where it intersects your axis, and p2.x and p2.y are the loop rotation. Set p2.z=0 and take the angle however. As PraeterB mentions, what counts as 0 degrees is arbitrary, but this is probably the most standard one (I think 0 degrees is “the most up”) and it will be consistant – if this says two points are at 30 and 50 degrees they really will be 20 apart.