I’m trying to make a top down orthographic camera that follows a car, zooms out when it speeds up and looks ahead in the direction of travel as it speeds up (the camera doesn’t rotate so it will look ahead according to the way the car is travelling). I’ve got a pretty rough version running that’s a mongrel of other people’s scripts but it’s pretty janky. Is there a way in Cinemachine that I can do any of these features in the interface or would it be script driven?
You could do it with minimal scripting.
If you are using CM 3, then we have a sample scene (SimpleCar Follow) showing the following setup (you can also implement it following these steps in CM 2):
-
Create an empty GameObject and add CinemachineMixingCamera component. This is going to mix its children CinemachineCameras (or CinemachineVirtualCameras) based on the weights, which will depend on the Speed of the car (more on this later).
-
Add two CinemachineCameras (or CinemachineVirtualCameras) as children of CinemachineMixingCamera.
-
Call one of them Cm Camera Slow and the other one Cm Camera Fast.
-
Set these CinemachineCameras up the way you like. For example, Cm Camera Slow is zoomed in and top down and Cm Camera Fast is zoomed out and looks a bit ahead.
-
Now you have the basic setup. The only thing you need is a script to modify the weights on CinemachineMixingCamera based on the car’s speed.
Add the following script to CinemachineMixingCamera (taken from our sample scene):
using UnityEngine;
namespace Unity.Cinemachine.Samples
{
[RequireComponent(typeof(CinemachineMixingCamera))]
public class MixCamerasBasedOnSpeed : MonoBehaviour
{
[Tooltip("At and above this speed, the second camera is going to be in control completely.")]
public float MaxSpeed; // max speed of your car
public Rigidbody Rigidbody; // RigidBody of your car
CinemachineMixingCamera m_Mixer;
void Start()
{
m_Mixer = GetComponent<CinemachineMixingCamera>();
}
void OnValidate()
{
MaxSpeed = Mathf.Max(1, MaxSpeed);
}
void Update()
{
if (Rigidbody == null)
return;
var t = Mathf.Clamp01(Rigidbody.velocity.magnitude / MaxSpeed);
m_Mixer.Weight0 = 1 - t;
m_Mixer.Weight1 = t;
}
}
}
If you are not using RigidBody to move your car, then you’ll need to slightly modify the above script to supply the Speed of the car differently.
Let us know if you need more help
Wow perfect, it’d have taken me a while to work that one out for myself! I do have a rigidbody so I’ll give it a whirl and report back
Works like a charm thanks! I just need to incorporate some degree of smoothness as my 3d map has sharp inclines which makes the camera jerk up with the car. Fiddling with the damping should do it I expect.