Ok, I’ll give a bit of an explanation so as to visualize how a quaternion works first. While working with Euler angles, we can visualize rotations quite easily, by just picking an axis (x,y,z) and assigning an angle in degrees to rotate and it’s that simple until you have to apply rotations to multiple axis at a time and this is when you can run into gimbal lock.
Quaternions on the other hand are much more flexible because you can escape from only having those three axis to work with and you can instead define your own axis. A quaternion takes 4 floats and the first 3 are the ones that define your axis. This is as simple as a direction vector. If you want to rotate around the y axis, the direction “before normalization” would be 0,1,0 or 0,-1,0. I say before normalization because quaternions are normalized in Unity (1 unit in length). The 4th float of a quaternion is the angle in radians which is 180/π degrees (so 0 to 1 radians is like saying 0 to 180 degrees in one direction and 0 to -1 Is like saying 0 to -180 degrees in the other direction where 1 and -1 are at the same orientation 180 degrees away from the initial orientation). Hope that makes sense… So quaternions will always just give you the shortest route to arrive to the target orientation, ie: 270 degrees is just -90 degrees away from 0 degrees, so that would be -0.5 in radians. So a -90 degree rotation around the y axis would look like this (0,1,0,-0.5).normalized or (0,-1,0,-0.5).normalized depending on which axis direction we are referring to.
So after saying all that. Unity actually simplified working with quaternions so you don’t have to remake the wheel. In your case, I would think the best way to apply the rotations of each given angle to find your target angle would be the following:
//I am assuming we are working in the objects local space
float y = 40.0f;
float x = 180.0f;
float z = 5.0f;
Quaternion initialRot = transform.rotation;
transform.rotation = Quaternion.AngleAxis(y, transform.up);
transform.rotation = Quaternion.AngleAxis(x, transform.right);
transform.rotation = Quaternion.AngleAxis(z, transform.forward);
Quaternion targetRot = transform.rotation;
So as you can see you can just add degrees into the function and it will turn it into a Quaternion for you which is quite convenient. Now you have the initial rotation and the target rotation. If you want to do a smooth rotation to the target, you would have to reset and interpolate from one to the other. You can use Slerp, Lerp or RotateTowards… Here is Slerp:
float timeScale = 0;
void Update(){
timeScale += Time.deltaTime;
transform.rotation = Quaternion.Slerp(initialRot, targetRot, timeScale);
if(timeScale >= 1.0f){
//reached the target rotation.
}
}
Hopefully that helps. Cheers