Set vcam zoom (orto size) based on player speed

I’m using a follow cinemachine camera, and I want the camera to zoom out when the player moves fast, up to a certain limit, and zoom in when they player slows down.

Is there any premade functions in cinemachine to achieve this, or should I write a custom script and connect my player speed to the orthographic size?

Thanks for any ideas!

1 Like

There a re a couple of approaches to this, but both require a little scripting.

Either do as you suggest (making sure to adjust the ortho size of the vcam, not the main camera), or you can try this other idea:

  • Create an invisible game object, with a custom script to place it always some distance in front of the player, with the distance scaled by the velocity
  • Add that object and the player to a CinemachineTargetGroup
  • Use that group as the vcam target
  • Set vcam’s FramingTransposer settings to frame the group the way you like it

Ah, thanks Gregoryl, that was an interesting approach, as it seems to let me adjust the framingtransposer instead of having variables in my code. I will definitely try it :slight_smile:

Hi again @Gregoryl ! I’ve now tried this, and got a decent result, but I still have some “jerkiness” when the framing transposer zooms in and out.

I made a short video that shows what I mean.

The orange dot is the “invisible game object” that is lerping in the direction the player is going. On the left you see when the orange frame expands (Framing transposer limits?), the vcam zooms out too quickly causing this jerkiness.

I tried both 0 and 20 on the X/Y damping, and I got different results how the camera moves while the ship is in the rectangle, but not how it changes the orthographic size.

Can you suggest any values I should tweak to fix this?

Also it seems to do some small jerks back and forth when it’s on max speed, but I’m not sure if it’s due to me playing in the editor, or anything else.

Thank you in advance!

The Z damping controls the damping on the ortho size change

Heej nicmarxp, I want to build something similar like your game. So I try to find a similar solution for the camera. But I’m new to Unity, and still learning programming. So my question to you is, how did you achieve that invisible game object to lerp like that? Is there a tutorial for this? In what direction should I look? Thanks for reading, have a great day you all.

Hehe, better late than never. This is what I created. I just ended up stop using it due to the camera jerking at higher speeds, so right now I’m back to just following the player, without changing the zoom, but I’m considering attaching a script to set the ortho based on velocity.

using System;
using UnityEngine;

namespace BlueGoo.Space {
    public class ForwardCameraTarget : MonoBehaviour {

        public Transform source;
        private ShipController2 shipController;
       
        [SerializeField]
        private float distanceScale;

        [SerializeField]
        private float maxDistance;

        [SerializeField]
        private float minDistance;

        [SerializeField]
        private float lerpSpeed = 1;
       
       
        private void Start() {
            // TODO: Assign player on start / Switch
            AssignPlayer();
        }

        public void AssignPlayer() {
            shipController = source.gameObject.GetComponent<ShipController2>();
        }

        private void Update() {
            var velocity = shipController.rb.velocity;
            var motionVector = velocity.normalized;
            var motionMagnitude = velocity.magnitude;
            var targetPosition = source.position + (Vector3)(motionVector *
                                                             (Mathf.Max(minDistance,
                                                             (Mathf.Min(maxDistance,motionMagnitude) * distanceScale)
                                                             )));
           
            transform.position = Vector3.Lerp(transform.position, targetPosition, lerpSpeed * Time.fixedDeltaTime);

        }
    }
}
2 Likes

Have you tried running it in a fixed or late update? The transform.position = Vector3.Lerp(transform.position, targetPosition, lerpSpeed * Time.fixedDeltaTime);

That may stop the jerkiness of the camera movement?

I’m trying to get the same effect for my game at the moment and looking at ideas.

Thanks, I have paused that for a little while, but I will get back to it soon and see if I did test that or not… :slight_smile: Let me know your results!