Skip to content

Instantly share code, notes, and snippets.

@CloudyWater
Last active February 28, 2016 05:17
Show Gist options
  • Save CloudyWater/8432782c6938bf13cfb6 to your computer and use it in GitHub Desktop.
Save CloudyWater/8432782c6938bf13cfb6 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CameraFollow : MonoBehaviour
{
private const float BOUNDING_BOX_PADDING = 1.5f;
private const float MINIMUM_ORTHO_SIZE = 3f;
private const float ZOOM_SPEED = 5f; //NEVER FORGET, I AM THE FASTEST MAN ALIVE
public Spawner mSpawner;
public float mDampTime = 0.15f;
public BoxCollider2D mLevelBounds;
private Vector3 mVelocity = Vector3.zero;
private Camera mCamera;
// Use this for initialization
void Start ()
{
mCamera = GetComponent<Camera> ();
}
// LastUpdate is called at the end of the update loop
void LateUpdate ()
{
Rect boundingBox = CalculateBoundingBox ();
Vector3 targetPosition = CalculateCameraPosition (boundingBox);
mCamera.orthographicSize = CalculateOrthographicSize (boundingBox);
//Make sure our camera isn't bigger than our level boundary
if (mCamera.orthographicSize > mLevelBounds.bounds.extents.y)
{
mCamera.orthographicSize = mLevelBounds.bounds.extents.y;
}
transform.position = Vector3.SmoothDamp (transform.position, targetPosition, ref mVelocity, mDampTime);
//If we're showing things outside the level, move the camera
if (transform.position.y - mCamera.orthographicSize < mLevelBounds.bounds.min.y)
{
transform.position = new Vector3 (transform.position.x, mLevelBounds.bounds.min.y + mCamera.orthographicSize, transform.position.z);
}
if (transform.position.y + mCamera.orthographicSize > mLevelBounds.bounds.max.y)
{
transform.position = new Vector3 (transform.position.x, mLevelBounds.bounds.max.y - mCamera.orthographicSize, transform.position.z);
}
if (transform.position.x + mCamera.orthographicSize * mCamera.aspect > mLevelBounds.bounds.max.x)
{
transform.position = new Vector3 (mLevelBounds.bounds.max.x - mCamera.orthographicSize * mCamera.aspect, transform.position.y, transform.position.z);
}
if (transform.position.x - mCamera.orthographicSize * mCamera.aspect < mLevelBounds.bounds.min.x)
{
transform.position = new Vector3 (mLevelBounds.bounds.min.x + mCamera.orthographicSize * mCamera.aspect, transform.position.y, transform.position.z);
}
}
//Calculates a bounding box around all the active players.
private Rect CalculateBoundingBox ()
{
float minX = Mathf.Infinity;
float maxX = Mathf.NegativeInfinity;
float minY = Mathf.Infinity;
float maxY = Mathf.NegativeInfinity;
//ZeroController is my character controller class. I just need the positions of the active players here.
List<ZeroController> activePlayers = mSpawner.GetActivePlayers ();
foreach (ZeroController controller in activePlayers)
{
Vector3 position = controller.transform.position;
minX = Mathf.Min (minX, position.x);
maxX = Mathf.Max (maxX, position.x);
minY = Mathf.Min (minY, position.y);
maxY = Mathf.Max (maxY, position.y);
}
return Rect.MinMaxRect (minX - BOUNDING_BOX_PADDING, maxY + BOUNDING_BOX_PADDING, maxX + BOUNDING_BOX_PADDING, minY - BOUNDING_BOX_PADDING);
}
//Gets the camera position, which is the bounding box's center x/y coords, and the camera's z coord.
private Vector3 CalculateCameraPosition (Rect boundingBox)
{
Vector2 boundingBoxCenter = boundingBox.center;
return new Vector3 (boundingBoxCenter.x, boundingBoxCenter.y, transform.position.z);
}
//Calculates the orthographic size of the camera.
private float CalculateOrthographicSize (Rect boundingBox)
{
float orthoSize = mCamera.orthographicSize;
if (Mathf.Abs (boundingBox.width / mCamera.aspect) > Mathf.Abs (boundingBox.height))
{
orthoSize = Mathf.Abs (boundingBox.width) / mCamera.aspect / 2f;
}
else
{
orthoSize = Mathf.Abs (boundingBox.height) / 2f;
}
return Mathf.Clamp (Mathf.Lerp (mCamera.orthographicSize, orthoSize, Time.deltaTime * ZOOM_SPEED), MINIMUM_ORTHO_SIZE, Mathf.Infinity);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment