Cinemachine: Interactive Cameras using C#

Gabriel Perez
5 min readMar 8, 2022

Switch and zoom in on targets using C#!

Objective

Set up a virtual camera so it can track two targets by pressing the ‘R’ key. When pressing the “Space” key, decrement the Field of View from 60, 40, and 20. Reset the Field of View to 60 when less than 20.

Targets

Lil Warbot Drone
Project Manager

Setting up a Virtual Camera

I create a new Virtual Camera and call it “VC1.” I change some of the properties:

  • Look At: Lil Warbot Drone (transform of the game object)
  • Field of View: 60
  • Far Clip Plane: 50
  • Lookahead Time: 0.25f
  • Lookahead Smoothing: 5.6f
  • Horizontal and Vertical Damping: 1.5f
  • Dead Zone Width: 0.17f
  • Dead Zone Height: 0.12f
  • Soft Zone Width and Height: 0.8f
Game Window Guides help visualize the changes of each property.

I tested out the changes on both targets, and I like how it feels.

Tracking Lil Warbot
Tracking Project Manager

Scripting

Next, I create a new script and call it “CameraSwitch.” I attach it to the Virtual Camera.

Since we will be dealing with Cinemachine, I need to make sure I add the namespace Cinemachine.

using Cinemachine;

I need to reference each target with a serialized field.

[SerializeField] private GameObject _target1, _target2;

Now I can drag and drop each target in the inspector.

Next, I need to hold a reference to the Virtual Camera and its Composer.

private CinemachineVirtualCamera _vcam1;
private CinemachineComposer _vcam1Comp;

Vcam1 variable will hold a reference for the Cinemachine Virtual Camera component. Vcam1Comp will hold a reference to the “Look At” target Aim settings. When I switch target to the Project Manager, I need to make sure the ‘Y’ position of the “Tracked Object Offset” is slightly higher around the chest/neck area for proper tracking.

Next, I create a bool to manage the logic to switch targets.

private bool _switch = false;

The last member variable will be a Vector 3 to hold a reference to the offset needed when switching between cameras.

Storing Reference

In the Start function, I need to hold references to some of the variables I created.

private void Start()
{
_vcam1 = GetComponent<CinemachineVirtualCamera>();
_vcam1Comp = _vcam1.GetCinemachineComponent<CinemachineComposer>();
offset = _vcam1Comp.m_TrackedObjectOffset;
}

Vcam1 holds a reference to the Cinemachine Virtual Camera component on the game object when we created the Virtual Camera. It is where the script is attached to, so we need access to its component by storing it into a variable.

Vcam1Comp holds a reference to Vcam1’s Composer algorithm properties. We need to access the “Tracked Object Offset” to change the ‘Y’ position when the camera targets the Project Manager.

The offset variable will hold a reference to the Tracked Object Offset property.

Switching Targets

I create a new method called “Switch Target.” It will handle the logic behind switching targets.

private void SwitchTarget()
{
_switch = !_switch;
}

I want to set a bool to toggle on and off when switching targets.

private void SwitchTarget()
{
_switch = !_switch;
switch (_switch)
{
case false:
_vcam1.LookAt = _target1.transform;
offset = new Vector3(0, 0, 0);
break;
case true:
_vcam1.LookAt = _target2.transform;
offset = new Vector3(0, 1.5f, 0);
break;
}
_vcam1Comp.m_TrackedObjectOffset = offset;
}

Next, I create a switch statement for when the bool is either false or true.

If false, I want Vcam1 to look at target 1’s transform, which is the drone, Lil Warbot. I also want to make sure the offset is reset by assigning a new Vector with 0 values. I want the virtual camera to track the drone near the center.

If true, I want Vcam1 to look at target 2’s transform, which is the Project Manager. I also want the ‘Y’ position of the offset to be a value of 1.5f. The virtual camera will track the Project Manager with an anchor around his chest/neck area.

Lastly, I want to assign the new value from the offset to the “Tracked Object Offset” property.

Testing Target Switching

When I press the ‘R’ key, the Look At target will change to the next target.

private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
SwitchTarget();
}
}

Switching FOV

Now that switching targets are working, let's change the Field of View when pressing the Space key.

I create a new method called “SwitchFOV.” It will handle the logic behind switching the Field of View of the virtual camera.

private void SwitchFOV()
{
int value = 20;
float fov = _vcam1.m_Lens.FieldOfView;
_vcam1.m_Lens.FieldOfView = fov — value;
}

The int variable will hold a value for the decrement of the Field of View. In this case, it is 20. We want it to go from 60 > 40 > 20 with each Space bar press.

Next, we need to store a reference of the virtual camera’s Field of View value. It will allow me to subtract the Field of View and the value 20, and assign it to the virtual camera’s Field of View property. I hope that makes sense?

private void SwitchFOV()
{
int value = 20;
float fov = _vcam1.m_Lens.FieldOfView;
_vcam1.m_Lens.FieldOfView = fov — value;
if (_vcam1.m_Lens.FieldOfView < 20 && Input.GetKeyDown(KeyCode.Space))
{
_vcam1.m_Lens.FieldOfView = 60;
}

}

If the Field of View is less than 20 and the Space key has been pressed, reset the Field of View back to 60.

Testing Zoom In On Target

When I press the “Space” key, I want to zoom in on the target. By zooming in, I mean by switching the FOV of the camera.

private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
SwitchTarget();
}
if (Input.GetKeyDown(KeyCode.Space))
{
SwitchFOV();
}

}

Conclusion

Hopefully, we have learned something from this! It is easy to access Cinemachine components through the use of C#. Just remember to use the Cinemachine namespace and store the Virtual Camera component in a variable to access its properties.

Gabriel

--

--

Gabriel Perez

Hello everyone, My name is Gabriel Perez, I am a Unity Developer and a creator who is always learning and experimenting.