Quaternion not returning expected angles

Greetings!
I am making a scene for testing audio localization in 3D space. My problem, at current, is that the Quaternion struct returns data that confuses me a bit. This is the first time I have used quaternions.

I have two vectors, and the following code is placed under Update.

refVec is the vector that points from the player to the audio source exactly, hence reference.

fwdVec is the vector that points in the direction that the player is actually looking.

tarSpawned is an instantiated game object

Essentially, what I want is to see how far off the fwdVec is in relation to the refVec as a set of mutually exclusive angle degrees (X, Y). The conversion that takes place after the data extraction is for converting the data from 0-360 degrees to 0-180, where 0 is a perfect match.
When I run the code, the Y value of qResult seems to return a perfectly usable value for the azimuth, but the X value does not make much sense to me. For the sake of testing the results, I had my tarSpawned object spawn at a set position (0, 2, 5) and locked the vertical axis of the camera, but both values still changed. Have I misunderstood quaternions? I have tried tracking the Z value as well, but it only showed me the inverted azimuth value.

I apologize if my code is not optimized.

 if (Input.GetButtonDown ("Fire1")){
            refVec = target.position - transform.position;
            qTemp = Quaternion.FromToRotation(refVec, fwdVec).eulerAngles;

            if (qTemp.x > 180)
            {
                qResult.x = 0 - (180 - (qTemp.x % 180));
            }
            else
            {
                qResult.x = qTemp.x;
            }
            if (qTemp.y > 180)
            {
                qResult.y = 0 - (180 - (qTemp.y % 180));
            }
            else
            {
                qResult.y = qTemp.y;
            }

            print(qResult);
            Destroy(tarSpawned);
            spawned = false;
              
  }

From the docs: “never access or modify individual Quaternion components (x,y,z,w)”

Instead, can look at qTemp.eulerAngles.x. The problem with those is they can be sort of random. You may think slightly up is -10 degrees on x (Unity uses a left-handed system,) but eulerAngles may suddenly decide it’s 350; or worse, that y is now 180 and x is 90+10=100. Quats are great when you just want to rotate smoothly, not so good if you need to break down into the x,y,z system.

Might have luck using the “flattening” trick (really projecting onto a plane) with Vector3 angles. For example (not tested, probably a cleverer, shorter way):

// bring to my local coords:
Vector3 localTargPos = transform.InverseTransformDirection(target.position);
localtargPos.x = 0; // flatten to up/down only
float xAngle = Vector3.Angle(Vector3.forward, localTargPos);

From the docs: “never access or modify individual Quaternion components (x,y,z,w)”

Thanks for the reminder. Unfortunately, your flattening trick did not seem to work. I tried fiddeling with it, but the Y values became really odd. I resorted to making a 3rd. vector that copied the properties of fwdVec (My perspective vector) and refVec. Thank you for the input, however :slight_smile:
Here is how I did it for the the two (Manually) signed values I wanted:

refVec = target.position - transform.position;
xVec = new Vector3(refVec.x, fwdVec.y, refVec.z );  // A new vector is created based on components of fwdVec and refVec. This new vector
persp = Vector3.Cross(fwdVec, refVec);              // sits on the same plane as fwdVec, so that only one dimension is taken into account.
dir = Vector3.Dot(persp, Vector3.up);               
if (dir < 0)                                        // The following if structure determines if the fwdVec is to the left or right of
{                                                   // refVec and sets results on the left to a negative value
	angle.x = Vector3.Angle(xVec, fwdVec);
}
	else
{
	angle.x = Vector3.Angle(xVec, fwdVec) * -1;
}


yVec = new Vector3(fwdVec.x, refVec.y, fwdVec.z);
if (fwdVec.y > refVec.y)
{
	angle.y = Vector3.Angle(yVec, fwdVec);
}
	else
{
	angle.y = -1 * Vector3.Angle(yVec, fwdVec);
}