Creating Virtual Cameras using Cinemachine in Unity

Cinemachine is a free, powerful tool for Unity. It provides a lot of features to achieve AAA quality camera behavior with little effort.

Cinemachine is an asset that is capable to perform a vast array of complex camera behaviour for your game project. Cinemachine is free of cost, a powerful tool for Unity developers and it provides a whole host of functionalities that enable players to achieve AAA quality camera behaviour. It suits a whole range of project scope, from a hyper-casual mobile game to a fully loaded RPG game. So, today we will discuss the installation process and some basic but most used functions of Cinemachine.

Installation of Cinemachine
First and foremost, go to the top menu and press on Windows > Package Manager.

Screenshot (584).png

Then, the Package Manager window will pop up. If you don't see the Cinemachine package, look for a drop-down menu above the list and select "All packages" and you can search for "Cinemachine" in the search bar and then you will have an option to import Cinemachine. Press on the "Import" button.

Screenshot (585)_LI.jpg

Usually, it won't take much time to import the Cinemachine asset. However, it depends on your computing resources.

Using Cinemachine

After the import gets complete, you will be able to see an option on the top menu called "Cinemachine". When you click on it you will see a list of options to create various Cinemachine cameras.

For this purpose, we will be selecting "Create Virtual Camera". A virtual camera is an object that instructs the main camera on what behaviour to perform. When you create a virtual camera, you will notice that there is a script called "CinemachineBrain" attached to the main camera. The script basically relays the behaviour from the virtual camera to the main camera. We also have various other kinds of Cinemachine cameras to achieve a variety of behaviours. For example, Free Look camera to achieve 3rd person free-look view.

Camera Follow using Virtual Camera

Once you select "Create Virtual Camera", you will see an object called "CM vcam" followed by a number. Now that you have added a virtual camera on your, your next step is to assign a subject to the virtual camera to follow. To achieve that you can simply drag the subject i.e. your game object that you want your camera to follow and drop it on the slot named "Follow". Then you adjust the offset of your camera to the player object based on your games preference from Body >> Follow Offset and tweak the values in X, Y and Z coordinates. We will be keeping the binding mode to "Lock To Target With World Up" as it works just fine.

After that, your camera must be following your player object just to find it. But you can see that when the player object makes a turn or changes direction, it gets out of the camera's view. It is because the camera is following the movement player, but it is not tracking the rotation of the player. In other words, the camera is not looking at the player. So, to achieve that we again drop the player object onto the slot named "Look At". Now, your camera must be staring at your player at its dead centre. That might not be the exact behaviour you want your camera to make. so to offset your camera where it looks at you can go to Aim >> Tracked Object Offset and tweak the values in X, Y and Z coordinates (Euler angles).

Screenshot (585).png

We will not be tweaking other values of the virtual camera because these settings will be enough for us to get our desired camera to follow behaviour. Our camera now must be following the player without writing any complicated script.

Blending Between Multiple Virtual Cameras

In a lot of games, we require to switch our cameras between various angles seamlessly. We can easily achieve that using Cinemachine with great amounts of flexibility with just a little amount of code. So, to blend between two or multiple cameras first we have to create a state-driven camera. To do that, we go to the top menu Cinemachine > Create State-Driven Camera. Then you will see a "CM StateDriven Camera"  on your hierarchy.

Screenshot (588).png

Now, you have to delete the child virtual camera of the state-driven camera and set all the virtual cameras that you want to blend as its child. You can simply select the virtual cameras and drop them on to the "CM StateDriven Camera" to make it your child. You can assure that by checking if the virtual cameras are referenced in the "Virtual Camera Children" list.

Screenshot (590).png

Now add a component "Animator" on your state-driven camera object and assign it to the slot named "Animated Target".

Screenshot (587)_LI.jpg
Screenshot (588)_LI.jpg

Create an "Animator Controller" by right-clicking on the Assets panel Create > Animator Controller. ||Assign the animator controller to the empty slot of the Animator which we just added.

Screenshot (592).png

Now double click on Animator Controller and add empty animation clips based on the number of virtual cameras you want to switch between. Name the animation clips appropriate to its virtual camera counterpart

Screenshot (594).png

Now under Custom Blends, you'll see a list where you can attach animation clip corresponding to its virtual camera. To achieve that we should press the "+" button and then select "All Unhandled State". Now select the virtual camera under the "Camera" drop-down to select the virtual camera.

Screenshot (596).png

For the scripting part, what we essentially doing is we are playing the animation clip and when we play the animation clip the main camera will switch to its virtual camera counterpart. So, we created a script named "BlendCameras.cs" and added it to the state-driven camera object.

private enum CurrentCamera
{
    VCam1,
    VCam2,
    VCam3
}

private Animator _animator;
private CurrentCamera _currentCamera;

private void Awake()
{
    _animator = GetComponent<Animator>();
}

First, we create an Enum will all the possible virtual cameras as its item and make _currentCamera of the same type to keep track of which virtual camera is currently in use. We also get a reference to our Animator in the Awake() method to play the empty animation clips.

public void SwitchCamera()
{
    switch (_currentCamera)
    {
        case CurrentCamera.VCam1:
            _animator.Play($"VCam1");
            _currentCamera = CurrentCamera.VCam2;
            break;
        
        case CurrentCamera.VCam2:
            _animator.Play($"VCam2");
            _currentCamera = CurrentCamera.VCam3;
            break;
        
        case CurrentCamera.VCam3:
            _animator.Play($"VCam3");
            _currentCamera = CurrentCamera.VCam1;
            break;
        
        default :
            Debug.Log("Not a proper CurrentCamera enum", this);
            break;
    }
}

Then we create a simple SwitchCamera() method to switch between cameras using a switch case statement. Here, we are simply checking which virtual camera is currently in use and based on it we switch to the next virtual camera by calling the corresponding animation clip and finally we assign _currentCamera to the currently active camera. We also check for an exception case, using Debug.Log(), in case something goes wrong.

private void Update()
{
    if (Input.GetKeyDown(KeyCode.C))
    {
        SwitchCamera();
    }
}

And to make sure our camera switch is working fine. We check it on the Update() method by calling the SwitchCamera() method when we press down the "C" key on our keyboard.

Customizing the Blend Between the Camera

When you play on the editor, you should experience a smooth transition between various virtual cameras. But, your game might need a different customized blend among the cameras. Well, that also can be achieved using Cinemachine very easily.

To create a custom blend between the cameras, we first go to the Custom Blends option and there you will find an empty slot and right next to it a button named "Create Asset".

Screenshot (589)_LI.jpg

Press the button and save the custom blend file generated in an appropriate location in your project. Now, you'll be able to see a list where you can add in what style or easing you want to blend between two virtual cameras.

Screenshot (598).png

You have arrays of options to choose from under "Style" on how to transition and the duration of transition under "Time".

The list of styles of ease that you can choose from are:

  • Cut
  • Ease In Out
  • Ease In
  • Ease Out
  • Hard In
  • Hard Out
  • Linear

For more detailed knowledge of these styles of transition and their easing type, check the official documentation here Blending between Virtual Cameras.

Thank you for reading till the end. I'll be posting more detailed guides like this in the future. Please leave any comments if you have any questions regarding the topic. Have a good day!