Created
December 6, 2017 01:37
-
-
Save codeimpossible/b98e2ec9aa9abcc84bf4cbe045e62523 to your computer and use it in GitHub Desktop.
Camera Controller for my 2D Game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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