How to measure rotation?

I have been researching this topic and I have found that it is quite a dicey topic

I have a cube and I need to read the current state of its rotation

I have read the article on quaternions by starmanta

https://starmanta.gitbooks.io/unitytipsredux/content/second-question.html

and so I have learned that the inspector cannot be relied upon for much, but i still dont understand it fully, so please bear with me

I have found that with this code I can measure the rotation on the Y axis:

Mathf.Atan2(transform.forward.x,transform.forward.z) * Mathf.Rad2Deg)

but I cant figure out how to measure for example the rotation on z after I have already rotated the cube by 90 degrees on Y

here is an image of my issue:

it seems that things seem to get dicey when I start compounding rotations, I guess that this is the general problem described on the starmanta article?

My goal is to find out, in some measureable human readable way, how much the cube is rotated, in other words, what face is currently facing the camera, and if its upside down, etc, I would need every detail of the current state of the rotation of the cube

since this cube is child of other objects which also rotate, its hard to manually keep track of the exact current rotation of the cube

I have the transform.rotation which is exactly what I need, the world quaternion of the cube, but thats not really human readable

I was looking for a way that I can output the exact WORLD rotation of the cube, in other words, to translate the quaternion in some sort of readable value

it doesnt matter to me if its a combination of values, and the format also doesnt really matter to me, it doesnt need to mirror the contents of the inspector, I just need some logical output of rotation that I can read and can then use then to create logic based on the state of the cube relative to the front facing camera.

Thanks!

Hi! You might want to look into the world of Euler Angles:

These are the representation of the rotation of a game object in the world space.

Transform.EulerAngles returns just that, but you might notice that the values of an “Euler-Angled” rotation might differ from the ones shown in the inspector if using this instruction; that’s because the inspector one relies upon the local space, and to get the actual correct value you want to use Transform.LocalEulerAngles:

You can also switch between Euler Angles and their Quaternion Representation using Quaterion.Euler:

Or vice-versa with Quaterion.eulerAngles:

Let me know if this quick overview helped you!

2 Likes

The Transform has shortcuts on it such as transform.forward and transform.right and transform.up

You can query those directly to find out things like:

  • which one is pointing up the most (dot product with Vector3.up)
  • which one is facing the camera the most (dot product with cam-to-object vector)
  • which two cubes are most aligned with each other
  • how aligned are any particular two things

etc…

Those vector ways of testing orientations are infinitely more useful in gamedev than anything to do with Quaternions or Euler angles.

Also, remember your trigonometry: the dot product can be turned back into a local relative angle using Mathf.Asin(); or Mathf.Acos(); (and Mathf.Rad2Deg if you want it in degrees).

2 Likes

Sometime I think vector arithmetics cant solve everything. But I’m by no means an expert on the subject.

Example one from our game

Slapping a charging handle in VR

        public void OnCollide(NVRHand hand, Collision col)
        {
            if(IsLockedBack)
            {
                var force = Vector3.Project(col.relativeVelocity, SlamDirection.up);

                var angle = Vector3.Angle(SlamDirection.up, col.relativeVelocity);

                if (angle < 60 && force.magnitude > 0.25f)
                {
                    ReturnSlide();
                    hand.ForceGhost();
                }              
            }
        }

Example two a revolver cylinder in a VR game

bulletAngleDelta = 360f / BulletContainer.Capacity;

private void SetRotation(float ratio)
{
	if (Locked)
	{
	    var angle = ratio * bulletAngleDelta + (currentIndex * bulletAngleDelta);
	    BulletContainer.transform.localEulerAngles = new Vector3(0, 0, angle);
	}
	firearm.TrySetCockedRatio(ratio);
}
2 Likes