Unity Beginner to Hero Part 7: Camera and Rotation Clamping

Right-oh let’s go Unity-ho! This is the chant I do every morning to pump myself up for another exciting day of Unity fun. Last time we made our controller’s head rotate with the mouse. This time we’ll make it to that the camera follows our character around, as well as refine the head movement.

In the Hierarchy, parent the Main Camera to the Head. Set it’s position to 0, 2, -5, and ensure it’s rotation is zeroed out and it’s scale all set to ones.

…and that’s it, really. Play the game, and you’ll have a rudimentary third-person player controller. And it only took seven short lessons. You might want to play around with some of the variables at this point. I increased the controller’s walk speed and slightly decreased the rotation speed to make the overall movement more comfortable.

However, you’ve probably noticed by now that our head movement has a small problem. If you keep rotating up or down, you’ll be able to turn the character’s neck in a full 360-degree circle, going completely upside down. Unlike for the horizontal rotation, we will need to set some limits onto the head’s rotation arc.

I was never really a fan of being upside down. Except that one really cool level in Majora's Mask.

I was never really a fan of being upside down. Except that one really cool level in Majora’s Mask.

Let’s modify the movement code. First off, we should specify the maximum and minimum allowed rotation angles. We’ll do this with two variables.

public float maxHeadRotation = 80.0f;
public float minHeadRotation = -80.0f;

We’ll also need a new variable to keep track of our head’s rotation. Add it at the top along with your public variables.

private float currentHeadRotation = 0;

This is called a private field, and is a variable that is accessible throughout the entire class. The other variables are public fields, and can accessed inside the entire class as well as from outside of it. Private fields by default do not appear in the Inspector, unlike public fields. They are useful for holding data that tells about the object’s state: a player’s health, the number of remaining bullets in a gun, how many coins they have collected, and so on. In this case this variable will store the head’s rotation angle, in degrees. Beforehand, we didn’t have a variable for this—we just rotated the head using the Rotate method and called it a day. However, because we want to clamp the rotation between two values (our min and maxHeadRotation), we need to know the head’s exact rotation. Replace the head.Rotate call with the following lines.

currentHeadRotation = Mathf.Clamp(currentHeadRotation + mouseInput.y * rotationSpeed, minHeadRotation, maxHeadRotation);

head.localRotation = Quaternion.identity;
head.Rotate(Vector3.left, currentHeadRotation);

The first line calls the Clamp method, which is a static function in the Mathf class. Mathf is Unity’s math function class, and contains common mathematical tools. Clamp is fairly simple: it takes a value in as the first parameter, and then results in a value clamped between the next two parameters that are minimums and maximums, respectively. E.g.,

Mathf.Clamp(12, 0, 10);

Would result in a value of 10, since 12 is larger than 10. Substituting -2 for 12 would then give you 0. Any value between 0 and 10 would remain unchanged.

You’ll notice something new here: we’re setting a variable (currentHeadRotation) to equal to the result of a function. This is because Mathf.Clamp returns a value after it has executed, allowing you to set it to a variable or perform other logic on it. You can see a method’s return type in it’s declaration: void Update() is a method with it’s return type set to void, in that it returns nothing. Clamp would be declared as float Clamp(float, float, float), in that it takes three floats and returns another float.

Our next line of code sets the head’s localRotation to something called Quaternion.identity. This is the identity rotation, stored as a Quaternion, which for now we can think of as the “zero rotation.” Essentially this line is saying to set the head’s local rotation to be zero, making it the same as it’s parent (the controller). Finally, we perform the rotation itself using the currentHeadRotation.

In simple terms, our new code does the following: each frame we modify currentHeadRotation based on mouse input, and then clamp it between our minimum and maximum values. Then, we reset the head’s rotation to zero, before finally rotating it by currentHeadRotation. Play the game and you’ll see that your can no longer spin your neck around.

Lesson 7 Complete Project

Thanks for reading! If you have any problems with the above tutorial, general comments or suggestions, please post below. It’s always appreciated!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s