SmoothLookAtWithZoom

I’m trying to create a camera system that simulates sporting event cameras. Basically a fixed point camera following the action and zooming in when things get exciting.

My idea is to use two objects, the player and their partner, and place a third target object between them. This target is what the camera will follow. I’ll then calculate the distance between the two players and adjust the zoom when they move closer and further apart.

Here’s what I have so far. I started with the SmoothLookAt.js script.

var target : Transform;//empty game object
var object1 : Transform;//player 1
var object2 : Transform;//player 2
var distancebetween = 0.0;
var zoomfactor = 2.0;//to control the zoom

var damping = 6.0;
var smooth = true;

function Update(){
	//move target between two objects
	target.position = ??
	//calculate distance between 2 objects
	distancebetween = (object1.position - object2.position).sqrMagnitude;
	//adjust the camera's field of view so that both objects are in view
	Camera.main.fieldOfView = distancebetween * zoomfactor;
}

function LateUpdate () {
	if (target) {
		if (smooth)
		{
			// Look at and dampen the rotation
			var rotation = Quaternion.LookRotation(target.position - transform.position);
			transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
		}
		else
		{
			// Just lookat
		    transform.LookAt(target);
		}
	}
}

function Start () {
	// Make the rigid body not change rotation
   	if (rigidbody)
		rigidbody.freezeRotation = true;
}

Obviously it’s missing a few bits so it doesn’t work yet. Could someone please help me fill in the blanks?

Made some progress and the script is working fairly well but I need to smooth out the changes in the zooming. I’m using Mathf.Clamp to keep the zooming under control but it is still a little jarring when the zoom changes too quickly.

var target : Transform;//empty game object
var object1 : Transform;//player 1
var object2 : Transform;//player 2
var distancebetween = 0.0;
var zoomfactor = .15;//to control the zoom

var damping = 6.0;
var smooth = true;

function Update(){
	//move target between two objects
	target.position = Vector3.Lerp(object1.position, object2.position, .5);
	//calculate distance between 2 objects
	distancebetween = (object1.position - object2.position).sqrMagnitude;
	//adjust the camera's field of view so that both objects are in view
	Camera.main.fieldOfView = Mathf.Clamp(distancebetween * zoomfactor, 20, 60);
}

function LateUpdate () {
	if (target) {
		if (smooth)
		{
			// Look at and dampen the rotation
			var rotation = Quaternion.LookRotation(target.position - transform.position);
			transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
		}
		else
		{
			// Just lookat
		    transform.LookAt(target);
		}
	}
}

function Start () {
	// Make the rigid body not change rotation
   	if (rigidbody)
		rigidbody.freezeRotation = true;
}

I got everything working. The smoothing on the zoom is a little crude but it seems to be working. I thought I’d post the final result in the event that it can help someone else or if it can be improved.

var target : Transform;//empty game object
var object1 : Transform;//player 1
var object2 : Transform;//player 2
var distancebetween = 0.0;
var zoomfactor = .15;//to control the zoom
var distanceArray = new Array(200);
var CurArrayValue = 0;

var damping = 6.0;
var smooth = true;

function Update(){
	//move target between two objects
	target.position = Vector3.Lerp(object1.position, object2.position, .5);
	//calculate distance between 2 objects
	distancebetween = (object1.position - object2.position).sqrMagnitude;
	//smooth distancebetween value
	distanceArray[CurArrayValue] = distancebetween;
	CurArrayValue++;
	
	if (CurArrayValue == 200){
		CurArrayValue = 0;
	}
	var TotalArray = 0;
	
	for (t=0;t<200;t++) {//add previous 200 values and divide by 200 to get a smoother average
		TotalArray += distanceArray[t]; 
	}

	distancebetween = TotalArray/100;
	
	//adjust the camera's field of view so that both objects are in view
	Camera.main.fieldOfView = Mathf.Clamp(distancebetween * zoomfactor, 20, 60);
}

function LateUpdate () {
	if (target) {
		if (smooth)
		{
			// Look at and dampen the rotation
			var rotation = Quaternion.LookRotation(target.position - transform.position);
			transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
		}
		else
		{
			// Just lookat
		    transform.LookAt(target);
		}
	}
}

function Start () {
	// Make the rigid body not change rotation
   	if (rigidbody)
		rigidbody.freezeRotation = true;
	// Fill smoothing array
	for (t=0;t<200;t++) {
		distanceArray[t] = 40; 
	}
		
}