Hi everyone!!!
One of the most difficult thing for a programmer to understand in the early stages of your 3D video game programming career is all the "rotation" world. I mean, 2D? Piece of cake. Just use Euler angles, no
Gimbal lock and everything works fine. But, when you enter the 3D world...oh my friend, the rotation of 3D objects can make your head spin at first.
Unity has many good options to rotate the gameobjects for easy stuff when you are learning Unity3D and testing: transform.LookAt will rotate the forward vector or your gameobject so it points to the target you want. Perfect for easy things like make enemies follow you in a really easy and little game.
Other good example is the Quaternion.Slerp function. It will rotate from one rotation to another one with a factor of X. Wait, are you thinking "what? quaterninon? what the hell is that?". Ok, we all do to ourselves these same question the first time. Long story short: a Quaternion is a way of storing the orientation of an object in 3D space. Actually the most used way in videagames. Why? It needs less math operations to use the Quaternions, and that's important in video games. If you want to know more about Quaternions...be my guest http://en.wikipedia.org/wiki/Quaternion
If you don't know what a Slerp is, may be this post is too much for you. Naaaaaaaaaaaa, it's a joke. Slerp is just a mathematical way of going from point A to Point B (rotation A and B in this case) in X time using Quaternoins. This is the quick explanation. Just think "rotate from this Quaternion to that Quaternion in X seconds".
So, we want to rotate our battleship "realistically" when the user goes upwards or downwards and return to neutral position when the user is not moving in the vertical axis. How can we achieve this? I'm not a superUnityProAAA programmer, but I managed to do this with Euler angles. Big, horrible, very horrible code. This should be inside our character's Update function.
Ouch, pretty awful...
I was trying to mix the Euler angles with the Quaternions and this "beast" code was the result. I realized one thing: you can't try to make use of Quaternions as with Euler angles. You have to abstract of the Euler angles and think "ok, I wanna rotate from here to there with Quaternions". You can't create a Quaternion that is a rotation of 90 degrees on X axis. At least not by numbers. We have to use the Unity3D great engine. So, we need to go from rotation of 0,0,0. The regular ship standing position to 45, 0, 0.
Ok, let's think in Quaternions: We wanna go from rotation A (0,0,0) to rotation B (45,0,0) in X seconds. So if we abstract from the Quaternion, we could think like this: we want to perform a Slerp from "thing" A to "thing" B. But, how do we make the "thing A"? Very easy with Unity.
Quaternion thing1 = Quaternion.Euler(0,0,0); //From rotation A
Quaternion thing2 = Quaternion.Euler(45,0,0); //To rotation B
transform.rotation = Quaternion.Slerp(thing1, thing2, 2.0f);
In three lines we have perform a perfect rotation with Spherical interpolation. Think of the Quaternion as an interpreter. Just something the SLERP needs.
So if we want our character to do this when we move in vertical axis, the code should be something like this (inside update function)
Quaternion fromRot = transform.rotation;
Quaternion toRot = Quaternion.identity;
if (Input.GetAxis("Vertical") > 0.0f) {toRot = Quaternion.Euler( 45,0,0); }
else if((Input.GetAxis("Vertical") < 0.0f){toRot = Quaternion.Euler(-45,0,0); }
else {toRot = Quaternion.Euler(0,0,0) } //neutral rotation
transform.rotation = Quaternion.Slerp(fromRot, toRot, 2.0f);
And there you go!! with these few lines we have a very nice rotation.
Thank you and leave some comments!!!!!