I am trying to rotate a (2D) gameObject around one of its corners (that is, it’s position + 0.5 scale).
To do that, I’m trying to calculate the angle by which it has already been rotateted like this:
Quaternion.Angle (myTransform.rotation, Quaternion.identity)
However, when this angle “should” be more than 180°, it becomes smaller again, measuring counter-clockwise (as seen from the camera) instead.
I may have misunderstood what Quaternion.Angle does here…
To understand what an angle calculation is doing, you need to think of it from a 3-Dimensional perspective. In a 3D space, and even moreso when considering Quaternion rotations in general, there is no definite axis by which you’re calculating an angle of rotation. 30 degrees around the Y+ axis is 100% identical to 330 degrees around the Y- axis; Quaternion.Angle will result in the smallest possible angle.
That said, hope is not lost. There are multiple ways to ascertain the extent to which your object is rotated in multiple directions:
-
[Mathf.Atan2()][1] can provide you with a signed angle (in radians) upon providing a pair of positions to act as an angle. For instance, you could use something like
float angle = Mathf.Atan2(myTransform.right.y, myTransform.right.x); // up/right
to determine your angle relative to the global “right” direction.
-
You’ve already determined your angle up to 180 degrees, so you can also add a simple conditional to determine which direction that angle is based around:
float angle = Quaternion.Angle(myTransform.rotation, Quaternion.identity);
float rightTest = Vector3.Dot(myTransform.up, Vector3.right);
if(rightTest < 0)
{
// Clockwise rotation.
// Change conditional to “>= 0” for Counter-Clockwise
angle *= -1;
}
[1]: Unity - Scripting API: Mathf.Atan2
try this (rotatePoint is a world position)
Vector3 rotatePoint;
float rotateAngle
transform.position-= rotatePoint;
transform.rotation= Quaternion.Euler(0,0, rotateAngle)*transform.rotation;
transform.position= Quaternion.Euler(0,0, rotateAngle)*transform.position;
transform.position+= rotatePoint;