Search

Crafting a Camera

Updated: Aug 22, 2019

One of the biggest things that stuck with me from my Game Dev Workshop classes is the importance of the 3C's: Character, Controls, and Camera. These have to do with how your game "feels" even before getting into things like the mechanics themselves or any kind of artwork. The very first work I did on Alien Cow Farm was to create a camera that behaved the way I wanted, and almost as importantly, was generic enough that I can now drop it into any future projects and have it work the same way there with minimum changes and hookup.


Unity comes with a built-in RotateAround() function which takes a point and an axis as arguments. This works great for the kind of spinning you see here, but I wanted to add some additional requirements to my camera. First, it needed to be able to rotate around the ship's y-axis as well (up and down), and I observed some strange gimbal lock when both axes of movement were combined. Second, I wanted to clamp this y-axis rotation so that you'd never be able to observe the ship upside down. Clamping became almost impossible with RotateAround(), because it would have involved comparing the absolute orientation value (after rotation was applied) with a known max value, then applying an opposite rotation back to within that bound if necessary. Instead, to get the kind of "free-rotation" you see below, I actually took a code snippet from S.P.A.R.K., where we reset the camera position each frame. I needed to store the last known position and orientation, calculate the change to apply based on input, clamp that if needed, and then place the camera there. This amounts to a "set to" rather than a "move by" approach, which was a lot safer for my needs.


The next decision was how the camera should interact with player movement. My main model was the Lego series of games, where player movement is always relative to camera forward. This means that if you press the movement stick left, your character will move left on the screen, regardless of which direction he was previously facing. Essentially, you can move the player and the camera independent of each other, but it still manages to feel very natural.

The Lego games include some other quirks which I decided not to implement, however. For instance, if the character is moving to the right or left, the camera will slowly and subtly swing around so that it's eventually directly behind them again. There's also a feature where moving the camera automatically rotates the player on the screen, as if they're actually "looking" towards where the camera is facing. I actually put functionality for both of these in, but decided I didn't like how they felt in my game...which, you'll remember, was the entire point of this exercise.


I added one more thing, a button that immediately resets the camera's position to its default relative to the ship. I just stored the original position/orientation combo and applied a MoveTowards() to the camera until it's current values matched that. The interesting thing is that this operation does take into account the character's facing direction, so afterwards the camera and player will share the exact same forward direction. But in this case it's the camera updating to match the character and not the other way around (which I didn't like).


Next time: a word on modeling and materials!