Nice looking Cinematic Cameras in Unity

A challenge you may face in your little programmers life of programming and Unity stuffs, is that you might be making a 3rd person game…. or even a 2D platformer… You know what, any game – mainly 3D, and you want a cinematic camera to do things.

Implementation 1

20131128025557
Touch: Something dark happening. A cinematic is needed.

Basically, the camera really needed to just sit there and move slowly in one direction. Originally, I made it start not moving, once it’s activated, it rotates in one direction and after a few seconds, cuts back to the player.

This was all well and good, but it meant that I couldn’t control easily WHERE the camera would end up afterwards, and it didn’t give much freedom in positioning the camera.

Implementation 2

The second idea was that the cameras LERP (Linear interpolation) between one transform and another. This was what it ended up being (with a little extra magic) but instead of just using plain transforms, I used actual cameras. The reason being is because you can SEE what the cameras can see at the start and end, and it made it a lot easier to position the cameras artistically (or cinematically, whatever).

20131128025250
All but a mess of camera frustum wires, but oh so useful it is.

But, the cameras were a bit jerky, (they went in a straight line and jerked to a halt at the end of their journey), so let’s make a curve LERP!

This was done by easing in the “t” in the “Lerp(t)” ¬†function from 0 to 1 (so, it’s not linear any more). The following code is what was used to do this:

float normalizedTime = m_timer / m_lerpTime;

if(normalizedTime > 1) normalizedTime = 1;

m_lerpProgress = normalizedTime * normalizedTime * (3.0f - 2.0f * normalizedTime);

m_cameraObject.transform.rotation = Quaternion.Lerp(m_lerpStart.rotation, m_lerpDestination.rotation, m_lerpProgress);

m_cameraObject.transform.position = Vector3.Lerp(m_lerpStart.position, m_lerpDestination.position, m_lerpProgress);

So as you can see… we Lerp the rotation and position of the camera based off the rotation and position of both a starting camera and a destination camera.

  • The “m_lerpProgress” is what is used as “t”
  • “m_lerpTime” is how long the camera needs to take to complete its journey
  • The “m_lerpProgress” needs to be from 0 to 1, so we need to use some calculations to figure this out based on our known time variables. This formula is… I can’t remember but it’s a popular easing formula for LERPing with a curve, and it works perfectly.

The last touch of magic is a lerp back to the player. To control this, the camera uses a finite state machine, because why not? And basically uses the EXACT same formula to LERP back to the player rather than to another camera within the cinematic camera list.

Ladies, form a line.

One thing of difficulty and noteworthiness is that each camera you use as the destination or start cameras needs to be DEACTIVATED, and also are not allowed to have any audio listeners, or anything really. They are simply references. So strip them down to their bones.

The other thing is that (despite me not doing this is the end game) is that there should really only be one camera in your scene. If you’re good, and you plan your game well before creating the camera system (like I wasn’t) you should be using the same camera your player uses as your cinematic cameras use. This is because a camera needs to have its settings correct (like fog colour and frustum distance). So design your camera systems around a single camera.