Making the camera look at the player while keeping another object in view

I'm working on a sorta football game where I need my player to always be at the center of the camera view while keeping the ball into view, without any vertical movement. The idea would be for the camera to act like the picture below.

What I came up with was the following code that I'm using in a LateUpdate. I'm computing a directional vector between the player and the ball and placing my camera behind the player using that data, and then I look at my player.

Vector3 ballPosition = ballTransform.position;
Vector3 playerPosition = playerTransform.position;

ballPosition.y = 0.0f;
playerPosition.y = 0.0f;

Vector3 directionVector = (ballPosition - playerPosition).normalized;
directionVector.y = 0.0f;

Vector3 newPosition = playerTransform.position - directionVector * 12.0f;
newPosition.y = 9.0f;

transform.position = newPosition;

transform.LookAt(playerTransform.position);


The code itself is working, but the camera movement is a bit nauseous, and when I'm trying to smooth it I end up with the ball leaving the camera field most of the time. Plus when I get too close from the ball I end up with some really quick camera movements which makes the whole thing kinda hard to follow. I tried to use a totally different technique by working with a Cinemachine Camera, but there doesn't seem to be an easy way to achieve such a view.

Does anyone have an idea of how to achieve such a thing?

This is less of a technical problem and more of a design problem. You've got the technical part right, now it's just playing with values. One solution could be to use the SmoothDamp function for the position of your camera

private Vector3 vel = Vector3.zero

LateUpdate() {
float dampTime = 3;
transform.position = SmoothDamp(transform.position, newPosition, ref vel, dampTime);
}


If you want to keep the ball in focus at all times, (which i'd advise having some leeway as you'll never be able to achieve this and have perfectly smooth camera all the time. Even fifa let's the ball go offscreen in edge cases) then you could change dampTime by a function of the ball's screen coordinates. If the ball is at the edge of the screen, follow faster, if it's close to the center we can follow slower. This value however is tricky to discern because ideally you'd want the camera to rotate at pace to keep the ball on screen. So maybe you'd want a function that takes the ball's 3D position and velocity relative to the camera frustum? Like I said this is definitely a design question, but SmoothDamp will make your life easier.

• That's what I tried to mess with and ended up not finding something satisfactory with, but I think playing with values is the best I can do to reach a satisfactory result. Thanks for those tips! – Isuka Apr 8 '19 at 7:13