More Interactive Cameras Using Cinemachine and C#
Previously we set up a system to switch targets with one input, and alter the FOV with the other. Check that out here. This only altered our Look At target though, and we have since dived in to the various Follow features, so let’s make the most of combining Follow and Look At targeting to create some more advanced interactive cameras!
For our first setup, we want to create a Third Person camera view, looking over the player’s shoulder, but on holding down the right mouse button, we want to switch to an orbiting camera to check out our player and the surrounding world, akin to Bethesda RPG’s.
Before we create any functionality, we first need to create our cameras. The benefit of Cinemachine is that we don’t need to get it perfect straight away! Being a dynamic system we can always make small adjustments later, so for now, we have a basic over the shoulder view set up.
This character controller uses the standard directional inputs to move around, and our forward rotation is dictated by the mouse. Now as our player moves around, our third person camera will stay behind the shoulder.
We now need an additional virtual camera for our second view. Using the Orbital Transposer Body type, we can quickly set up a circular track around our player. The X axis is controlled by the mouse position, so we can move around our track.
As we move around though, we need our camera to also Look At the player. We could use the Same As Follow Target Aim mode, but since we are using a vertical offset, we need to make use of the Composer to keep our player vertically centered.
Since we have our Input Axis Value inverted, the camera orbits in the opposite direction to the player rotating. Currently, this works well, but in other circumstances, we may need to add additional logic to lock the player’s rotation control when accessing this virtual camera.
With our two cameras set up though, we can now create the switching logic. Creating a script that accesses the two virtual cameras in the Inspector, allows us to set the priorities. Then all we need to do, is check for Input from the Right Mouse button, and if so, switch the priority of the Orbital camera to be higher than the POV, otherwise, it’s lower.
The neat thing about Cinemachine, is that it handles all our transitions smoothly by default!
The second camera system I created, makes use of gameplay triggers. What we want to achieve, is that, as the player passes through each of these red objects, a trigger is called to change between various cameras. By default we want our previously created Third Person camera. Passing through the first trigger, switches to a Bird’s Eye view, the second moves to a panning Dolly track, and the third is a fixed position camera, mimicking something akin to a security camera. On the last trigger, we return to the default.
To start, we need our various cameras. The Third Person is already working, so we can next create our Bird’s Eye view. For now, I’m simply using no Damping on the Aim features of any of these cameras, just to get the functionality right, but we could very easily make each camera a lot more dynamic if we desired.
Next, the Dolly camera, which requires a Path. I’ve simply set two points within the appropriate trigger zone, for the virtual camera to move along.
To set the camera itself up though, we should move our player to the approximate position it will be in. Passing in the Path’s game object, we can get our virtual camera looking and following our target along said path.
Lastly, we want to create our ‘Security’ camera. Again, this camera will benefit from the player being in a suitable position to set up. Our Body is set to Do Nothing, preventing any directional movement. All we have is a slight Dutch of the Lens, and a simple Aim setup to track the player.
With our four cameras setup, we can now focus on functionality. Each cube object has a Box Collider set to Is Trigger, and each hold a custom script called Camera Trigger.
To make this system modular, I set all usable Virtual Cameras as a child of one game object, so we can access all CinemachineVirtualCamera components and dynamically populate an array from one object.
In the Inspector, we can also dictate which camera each trigger represents, which we will then pair to our array index later.
Now, OnCollisionEnter, we check for the player. Then we can use a for loop to cycle through each camera in the array and check if it matches our int value we created above. If we find a match, we set that virtual camera’s priority to the highest. For all the other cameras, as they are cycled through, their priority is set to a lower value.
To dictate a default camera, instead of relying on Cinemachine’s selection when all cameras have the same priority, we can lastly set our first camera (the Third Person POV camera) to have a priority higher than our lowest values, but not high enough to interfere if a trigger has successfully worked!
Now we can test it out!
One small issue with this setup, is that if we want to backtrack, the camera switch won’t happen until we are at the start of that zone. Instead, we could create larger volumes between each box, that does the triggering instead — covering a ‘zone’ instead of walking through one marker.