Need Help Finding The Problem In This Code
So I am working on a script that controls the camera. It is for a 2.5D game from the side perspective. I need the camera to remain a perspective camera so that the 3D features are still visible. The camera will move on the x/y axis so it will constantly be looking at the center of all players. It will move on the z axis to zoom in and out to make sure all players are on screen. The movement to look at the center is working, but the zoom is not. The code is done in C# and must remain so. I have taken a look at the tutorial projects, but could not find any solutions. Thank you for any help.
using UnityEngine;
using System.Collections;
public class CameraMovement : MonoBehaviour {
// Private variables
private GameObject[] players; // Array of players in the game
private Camera cam; // The camera caponent on the main camera
private float xpos, ypos, zpos; // The x, y, z position the camera wants to be at
private float minx, miny, maxx, maxy; // The Min and Max x,y positions of players
private bool zoomOut; // A Bool to track if the camera should move positivly or negativly on the z axis
// Public Variables
public float MinZoom; // The furthest the camera will zoom out from the players
public float MaxZoom; // The closest the camera will zoom in to the players
public float Speed = 2; // How fast the camera will move
// Use this for initialization
void Start ()
{
players = GameObject.FindGameObjectsWithTag("Player"); // Find all the players in the scene
cam = transform.GetComponent<Camera>(); // Store the camera caponent
}
// Update is called once per frame
void Update ()
{
findCenter(); // Find center of players
Zoom(); // Find our Min/Max positions
Vector3 CamMin, CamMax; // The Min/Max boarders of the screen
CamMin = cam.ViewportToWorldPoint(new Vector3(0, 0, 0)); // Set the Min boarders
CamMax = cam.ViewportToWorldPoint(new Vector3(1, 1, 1)); // Set the Max Boarders
if (CamMin.x < minx - 1 || CamMin.y < miny - 1 || CamMax.x > maxx + 1 || CamMax.y > maxy + 1) // If any player is out of the boarders
{
zpos = -1000; // Set the wanted z position to zoom out direction
zoomOut = true; // Track that we want to zoom out
}
else // if not then we want to zoom in
{
zpos = 1000; // Set the wanted z position to zoom in direction
zoomOut = false; // Track that we want to zoom in
}
if (transform.position.z > MaxZoom && !zoomOut) // If we want to zoom in but we are already max zoomed in
zpos = MaxZoom; // Set the wanted z to max zoomed
else if (transform.position.z < MinZoom && zoomOut) // Else if we want to zoom out, but are already at the furthest point
zpos = MinZoom; // Set the wanted z to out max distance
Vector3 target = new Vector3(xpos, ypos, zpos); // Create our movement target
float step = Speed * Time.deltaTime; // Creat the step for movement
transform.position = Vector3.MoveTowards(transform.position, target, step); // Move the camera towards our target
}
void findCenter() // A function to find our players average position
{
// temp cariables to store our players average x and y
float y = 0;
float x = 0;
foreach (GameObject player in players) // loop through all the players
{
// add their x and y to the temps
y += player.transform.position.y;
x += player.transform.position.x;
}
// find the average, and set the positions
ypos = y / players.Length;
xpos = x / players.Length;
}
void Zoom() // a function to find players min/max positions
{
// set min/max to a value that is way out of range
minx = 1000;
maxx = -1000;
miny = 1000;
maxy = -1000;
foreach (GameObject player in players) // loop through all players
{
if (player.transform.position.x < minx) // if the player's x is lower than our min
minx = player.transform.position.x; // set it to the min
if (player.transform.position.x > maxx) // if the player's x is higher than our max
maxx = player.transform.position.x; // set it to the max
if (player.transform.position.y < miny) // if the player's y is lower than our min
miny = player.transform.position.y; // set it to the min
if (player.transform.position.y > maxy) // if the player's y is higher than our max
maxy = player.transform.position.y; // set it to the max
}
}
}
Answer by callen · Dec 28, 2015 at 08:08 PM
I've modified your Update() function below to correct a mistake made in your ViewportToWorldPoint calls and a spot where you may have gotten your logic backwards. However you didn't specify what wasn't working about the zoom so I can't be 100% sure this is it. Let me know if it helps:
void Update ()
{
findCenter();
Zoom();
Vector3 CamMin, CamMax;
float testDistanceZ = -cam.transform.position.z;
CamMin = cam.ViewportToWorldPoint(new Vector3(0, 0, testDistanceZ));
CamMax = cam.ViewportToWorldPoint(new Vector3(1, 1, testDistanceZ));
Vector2 playerMin = new Vector2(minx - 1, miny - 1),
playerMax = new Vector2(maxx + 1, maxy + 1);
zoomOut = (CamMin.x > playerMin.x || CamMin.y > playerMin.y ||
CamMax.x < playerMax.x || CamMax.y < playerMax.y);
zpos = (zoomOut ? MinZoom : MaxZoom);
if (transform.position.z > MaxZoom && !zoomOut)
zpos = MaxZoom;
else if (transform.position.z < MinZoom && zoomOut)
zpos = MinZoom;
Vector3 target = new Vector3(xpos, ypos, zpos);
float step = Speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target, step);
}
Doing the changes with testDistanceZ helped, but the zoom is still not working. Before it wasn't doing anything now it does zoom in/out on occasion. As for switching the - for zpos, it may look a bit confusing, but thats just how the scene is set up it is right the way it was before.
It is hard to describe what the camera is doing here's a link to the project on google drive:
https://drive.google.com/file/d/0BzotAsawmvA4cjRCSU51S3J4Zm$$anonymous$$/view?usp=sharing
Thanks for your quick answer!
One $$anonymous$$or bug has been fixed in the code above. Changing this line made everything work in your sample project.
Before:
float testDistanceZ = 0;
After:
float testDistanceZ = -cam.transform.position.z;
Isn't it funny how the one line of code with the huge comment-explanation was the one that turned out to be wrong? Lol.
Is that the only line you altered from your original post?