Skip to content

Instantly share code, notes, and snippets.

@codeimpossible
Created December 6, 2017 01:37
Show Gist options
  • Save codeimpossible/b98e2ec9aa9abcc84bf4cbe045e62523 to your computer and use it in GitHub Desktop.
Save codeimpossible/b98e2ec9aa9abcc84bf4cbe045e62523 to your computer and use it in GitHub Desktop.
Camera Controller for my 2D Game
using UnityEngine;
public class CameraController2D : MonoBehaviour
{
public Transform ObjectToFollow;
public Camera CameraToMove;
public Vector2 CameraPositionOffset = Vector2.zero;
public Vector3 CameraTrackingBox = Vector3.one;
public float CameraMoveSpeed = 5f;
public float VerticalMovementTrackingSpeed = 5;
public float FudgeFactor = 0.2f;
public bool MoveToObjectPositionAtStart = false;
private Vector3 _targetPosition;
private float _framesSinceVerticalMovementChange = 0;
private bool _verticalPositionChanged = false;
private enum InternalCameraState
{
Waiting,
TrackingBoth,
TrackingHorizontal,
TrackingVertical,
}
private InternalCameraState _cameraState;
private Vector3 _velocity = Vector3.zero;
private void Start()
{
CameraToMove = CameraToMove ?? Camera.main;
ObjectToFollow = ObjectToFollow ?? transform;
if (MoveToObjectPositionAtStart)
{
CameraToMove.transform.position = new Vector3(
ObjectToFollow.transform.position.x,
ObjectToFollow.transform.position.y,
CameraToMove.transform.position.z) + (Vector3)CameraPositionOffset;
}
}
private void Update()
{
var z = _targetPosition.z;
var center = CameraToMove.transform.position;
var pos = ObjectToFollow.transform.position + (Vector3)CameraPositionOffset;
if (_verticalPositionChanged)
{
_framesSinceVerticalMovementChange = Mathf.Approximately(_targetPosition.y, pos.y) ? _framesSinceVerticalMovementChange + 1 : 0;
Debug.Log("vertical move update: " + _framesSinceVerticalMovementChange);
if (_framesSinceVerticalMovementChange >= VerticalMovementTrackingSpeed)
{
Debug.Log("vertical move done");
_verticalPositionChanged = false;
_framesSinceVerticalMovementChange = 0;
if (_cameraState == InternalCameraState.TrackingHorizontal) _cameraState = InternalCameraState.TrackingBoth;
else _cameraState = InternalCameraState.TrackingVertical;
}
}
if (!_verticalPositionChanged && !Mathf.Approximately(_targetPosition.y, pos.y))
{
Debug.Log("vertical move: " + _framesSinceVerticalMovementChange);
_verticalPositionChanged = true;
_framesSinceVerticalMovementChange = 0;
}
_targetPosition = pos;
if ((_cameraState == InternalCameraState.Waiting || _cameraState == InternalCameraState.TrackingVertical) && !InTrackingBox(_targetPosition))
{
_cameraState = _cameraState == InternalCameraState.Waiting ? InternalCameraState.TrackingHorizontal : InternalCameraState.TrackingBoth;
}
if (_cameraState != InternalCameraState.Waiting)
{
var move = Vector3.SmoothDamp(center, _targetPosition, ref _velocity, CameraMoveSpeed);
CameraToMove.transform.position = new Vector3(
_cameraState == InternalCameraState.TrackingVertical ? CameraToMove.transform.position.x : move.x,
_cameraState == InternalCameraState.TrackingHorizontal ? CameraToMove.transform.position.y : move.y,
CameraToMove.transform.position.z);
}
if (_cameraState != InternalCameraState.Waiting && Utility.Approximately(center.x, _targetPosition.x, FudgeFactor))
{
_cameraState = _cameraState ==
InternalCameraState.TrackingHorizontal ?
InternalCameraState.Waiting :
_cameraState == InternalCameraState.TrackingBoth ?
InternalCameraState.TrackingVertical :
InternalCameraState.TrackingVertical;
}
if (_cameraState != InternalCameraState.Waiting && Utility.Approximately(center.y, _targetPosition.y, FudgeFactor))
{
_cameraState = _cameraState ==
InternalCameraState.TrackingVertical ?
InternalCameraState.Waiting :
_cameraState == InternalCameraState.TrackingBoth ?
InternalCameraState.TrackingHorizontal :
InternalCameraState.TrackingHorizontal;
}
}
private bool InTrackingBox(Vector2 position)
{
var trackingBoxDim = GetTrackingBox();
return trackingBoxDim.Contains(position);
}
private Rect GetTrackingBox()
{
var center = CameraToMove.transform.position;
return new Rect(center.x - CameraTrackingBox.x / 2, center.y - CameraTrackingBox.y / 2, CameraTrackingBox.x, CameraTrackingBox.y);
}
private Vector3 NormZ(Vector3 v, float z)
{
return new Vector3(v.x, v.y, z);
}
private void OnDrawGizmos()
{
if (CameraToMove != null)
{
var z = _targetPosition.z;
var a = (_targetPosition.y - CameraToMove.transform.position.y);
var b = (_targetPosition.x - CameraToMove.transform.position.x);
var center = NormZ(CameraToMove.transform.position, z);
if (InTrackingBox(_targetPosition))
{
Gizmos.color = Color.green;
}
else
{
Gizmos.color = Color.red;
}
Gizmos.DrawWireCube(center, CameraTrackingBox);
Gizmos.color = Color.yellow;
Gizmos.DrawLine(center, _targetPosition);
Gizmos.color = Color.blue;
Gizmos.DrawLine(center, center + new Vector3(0, a, 0));
Gizmos.color = Color.red;
Gizmos.DrawLine(center + new Vector3(0, a, 0), center + new Vector3(b, a, 0));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment