In the Third Person Zombie Shooter game, I needed to create a functional camera. The Camera needs to rotate both horizontally and vertically with the mouse movement— of course, within a certain range to prevent it look unrealistic.
If you think of a TPS or FPS game, you will realize that the player is rotating with full body horizontally. Whereas for the vertical look, the body stays steady but it is more like a move of head. I have already childed the camera under the Player to make sure that Main Camera always follows the Player. Thus, the rotation on the X axis (left &right) will be rotating the player himself/herself. On the contrary, the rotation on the Y axis will only be rotating the camera.
To look up and down, we need to manipulate the X-axis rotation on the camera whereas for looking left and right, Y-axis rotation needs to be manipulated. Since we will rotate according to the mouse position, the camera needs to get the input data from the mouse position. I have created a seperate script for handling the rotation according to mouse input.
To eliminate the Risk of Gimbal Lock, we need to use Quaternions rather than Euler Angles. Unity handles the rotations with Quaternions and displays it with Euler Angles so that we can have a better understanding of it. Gimbal lock is simply losing a degree of freedom, that results in rotation in 2D. For a better explanation, I suggest you to watch https://www.youtube.com/watch?v=rrUCBOlJdt4 .
Local Space vs World Space
The code I have shared above will work. However, we are facing an additional issue. On the scene above, I have kept pressing ‘W’ key to move the player forward, in other words, tried to move the player forward (Vector3 forward). Regardless of the player’s rotation (the way we look), the player keeps moves forward. This is because of the fact that Player script tells the player to move according to the World Space, rather than the Local Space.
As can be seen below, the Global Axis expectedly stays constant, independent of the Player’s rotation. Thus, we need to find a way to make this Global.
transform.TransformDirection is used to change a Vector3 from local space to global space. For more information, check Unity Manual from here.
So if we update the _velocity variable, the problem will be fixed.
Lastly, we need to clamp the camera to limit the player’s vertical look angles. Meanwhile, I have also added a crosshair. By manipulating the X value of the camera, I have decided to set the rande in between 0 and 28. Here’s the revised code:
Works like a charm!