SmoothFollow 2 Moving Players?

Hi. I am currently working on an iPhone game which requires the camera to follow two separate moving objects (top-down camera setup). For instance, as the two players move further away from each other, the camera would zoom out to keep both players on screen. If the players get closer, the camera zooms in, keeping them both in the frame.

Anyone have any ideas on how this is done?

I would do something like this:

  1. Find the xz-distance between the two objects. Use that to set the Y for the camera.

  2. Find the xz-middle-point between the two objects and use that to set X and Z for the camera.

Some pseudo code:

distanceApart = sqrt(pow(x1-x2, 2) + pow(z1-z2, 2))
camera.y = distanceApart * 3 // where 3 is some suitable value

middleX = (x1-x2)/2+x1
middleZ = (z1-z2)/2+z1
camera.x = middleX
camera.z = middleZ

Okay, so I’ve gotten this far:

var target : Transform;
var target2 : Transform;

function Update () {
	y1 = target.transform.position.y;
	y2 = target2.transform.position.y;
	x1 = target.transform.position.x;
	x2 = target2.transform.position.x;
	z1 = target.transform.position.z;
	z2 = target2.transform.position.z;
	
	dist = (y1-y2)/x1-x1;
	middleX = (x1-x2)/2+x1;
	middleZ = (z1-z2)/2+z1;
	
	camera.transform.position = (middleX, dist, middleZ);
}

Any ideas on where to go next? The script doesn’t work in it’s current state.

The distance calculation uses the wrong parameters and is not correct at all. Otherwise, I think the code is fine (if you have made sure that the camera points downwards somewhere else).

The distance is needed because you want the camera Y (height) to increase when the distance between the objects are greater, right? Therefore, use Phytagoras to find the distance between the two points on the ground (x and z).

The code might not be 100 % correct but you should be able to find it in the docs for Mathf.

dist = Mathf.SquareRoot((x1-x2)(x1-x2)+(z1-z2)(z1-z2)));

Also, remember that you might want to multiply dist by something if the camera gets overall too close or too far away.

Okay, so so far I’m at:

var target : Transform;
var target2 : Transform;

function Update () {
	y1 = target.transform.position.y;
	y2 = target2.transform.position.y;
	x1 = target.transform.position.x;
	x2 = target2.transform.position.x;
	z1 = target.transform.position.z;
	z2 = target2.transform.position.z;
	
	dist = Mathf.Sqrt((x1-x2)*(x1-x2)+(z1-z2)*(z1-z2));
	middleX = (x1-x2)/2+x1;
	middleZ = (z1-z2)/2+z1;

}

However, I’m not quite sure if the first portion works (defining the y,y1,x,x1, etc). Also, I have no way of assigning the middleX, middleZ, and dist to the camera’s coordinates. Thanks for your help, but any more ideas?

The assigning part looks good. It makes the code very readable.

Assigning the camera position should be a quick fix. Try this (I only work with C# so you might have to alter my code a little bit):

var camera : Transform;
var target : Transform;
var target2 : Transform;

function Update () {
y1 = target.transform.position.y;
y2 = target2.transform.position.y;
x1 = target.transform.position.x;
x2 = target2.transform.position.x;
z1 = target.transform.position.z;
z2 = target2.transform.position.z;

dist = Mathf.Sqrt((x1-x2)(x1-x2)+(z1-z2)(z1-z2));
middleX = (x1-x2)/2+x1;
middleZ = (z1-z2)/2+z1;
camera.position = new Vector3(middleX, distance, middleZ);
}

Okay, so after a little googling and a futile attempt to remember geometry, I found the equation for the distance between two points is:

x1+x2/2

which makes sense, because you’re basically trying to find the average of the two points. That has been altered in the script accordingly. However, the script still doesn’t work. It DOES change the camera’s position, but not to the right position, and the camera doesn’t track the subjects. Once I hit “play”, the camera snaps into position, but never moves after that.

P.S.
I’ve been using:

http://www.unifycommunity.com/wiki/index.php?title=SmoothFollow2

for reference. It’s the smoothfollow script for 1 object in both javascript and C#

Of course you are right about the middle point. Dont know what I was thinking about. This script works like a charm:

var myCam: Transform;
var target : Transform;
var target2 : Transform;

function Start ()
{
var q = Quaternion.identity;
q.SetLookRotation(Vector3.down, Vector3.forward);
myCam.rotation = q;
}

function Update ()
{
y1 = target.transform.position.y;
y2 = target2.transform.position.y;
x1 = target.transform.position.x;
x2 = target2.transform.position.x;
z1 = target.transform.position.z;
z2 = target2.transform.position.z;

dist = Mathf.Sqrt((x1-x2)(x1-x2)+(z1-z2)(z1-z2));
middleX = (x1+x2)/2;
middleZ = (z1+z2)/2;
myCam.position = new Vector3(middleX, dist, middleZ);
}

Finally! That worked exactly as hoped! Thank you so much. I just have one last request. I’m going though the script adding variable multipliers like this:

var myCam: Transform; 
var target : Transform; 
var target2 : Transform; 
var heightDisplacement = 2.0;
var xDisplacement = 0.5;
var yDisplacement = 0.5;

function Start () { 
	var q = Quaternion.identity; 
	q.SetLookRotation(Vector3.down, Vector3.forward); 
	myCam.rotation = q; 
} 

function Update () { 
	y1 = target.transform.position.y; 
	y2 = target2.transform.position.y; 
	x1 = target.transform.position.x; 
	x2 = target2.transform.position.x; 
	z1 = target.transform.position.z; 
	z2 = target2.transform.position.z; 

	dist = Mathf.Sqrt((x1-x2)*(x1-x2)+(z1-z2)*(z1-z2)*heightDisplacement+yDisplacement); 
	middleX = (x1+x2+xDisplacement)/2;
	middleZ = (z1+z2)/2; 
	myCam.position = new Vector3(middleX, dist, middleZ);
}

The only problem is, I’m working on an iPad application. So, if the characters go too far to the left or right, they end up going off the screen. So, how could I do something like this:

if (middleX > 3.0){
		middleX*middlexMultiplier;
	}

Again, thank you so much for all your help and patience.

About naming conventions… You should try not to call different things alike. Call heightdisplacement heightmultiplyer or heightfactor. That way, you will easier understand your code in a few months.

Your problem will be seen on any screen. More mathematics. :slight_smile: From the top of my head, you should be able to find values for ydisplacement and heightmultiplyer that fits the camera fov (field of view). Either test until you get there or use pen and paper and draw the scenario seen from the side, where the camera view basically becomes a triangle, and use you math skills. :wink: