Advertisement
AnomalousUnderdog

PerspectiveSwitcher

Jun 2nd, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.03 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4.  
  5.  
  6. namespace Victis.CameraSystem
  7. {
  8.  
  9. [RequireComponent (typeof(Camera))]
  10. public class PerspectiveSwitcher : MonoBehaviour
  11. {
  12.     static PerspectiveSwitcher _singleton;
  13.     public static PerspectiveSwitcher Singleton { get{ return _singleton; } }
  14.  
  15.     Matrix4x4 _perspective;
  16.     Matrix4x4 _targetProjection;
  17.  
  18.     [SerializeField]
  19.     float _fov = 60f;
  20.  
  21.     [SerializeField]
  22.     float _near = 0.01f;
  23.  
  24.     [SerializeField]
  25.     float _far = 1000f;
  26.  
  27.     [SerializeField]
  28.     float _orthographicSize = 4f;
  29.  
  30.     public float OrthographicSize { get{ return _orthographicSize; } set{ _orthographicSize = value; } }
  31.  
  32.     [SerializeField]
  33.     float _orthoNear = -110;
  34.  
  35.     float _aspect;
  36.  
  37.     bool _orthoOn;
  38.     public bool OrthoOn { get{ return _orthoOn; } }
  39.  
  40.     bool _orthoSwitchFinished;
  41.     public bool OrthoSwitchFinished { get{ return _orthoSwitchFinished; } }
  42.  
  43.     [SerializeField]
  44.     float _transitionToPerspectiveSpeed = 1.0f;
  45.  
  46.     [SerializeField]
  47.     float _transitionToOrthographicSpeed = 1.0f;
  48.  
  49.     float _transitionSpeed = 1.0f;
  50.     public float TransitionSpeed { get{return _transitionSpeed;} }
  51.  
  52.     [SerializeField]
  53.     Camera _orthoCam;
  54.  
  55.     [SerializeField]
  56.     bool _startInOrtho;
  57.  
  58.     [SerializeField]
  59.     float _cameraTiltWhenInIso = 45f;
  60.  
  61.     CamRotLeftRight _camX;
  62.     CamRotUpDown _camY;
  63.     CameraCollider _camCollider;
  64.     CamMovement _camMove;
  65.     float _camYLastY = 0.0f;
  66.  
  67.     public Camera CameraUsed { get{ return _orthoOn ? _orthoCam : camera; } }
  68.  
  69.  
  70.     const int CAM_DEPTH_ABOVE = -10;
  71.     const int CAM_DEPTH_BELOW = -20;
  72.  
  73.     void ShowOrthoCam()
  74.     {
  75.         //_orthoCam.depth = CAM_DEPTH_ABOVE;
  76.         //camera.depth = CAM_DEPTH_BELOW;
  77.  
  78.         camera.orthographic = true;
  79.         camera.nearClipPlane = _orthoNear;
  80.     }
  81.  
  82.     void ShowPerspectiveCam()
  83.     {
  84.         //camera.depth = CAM_DEPTH_ABOVE;
  85.         //_orthoCam.depth = CAM_DEPTH_BELOW;
  86.  
  87.         camera.orthographic = false;
  88.         camera.nearClipPlane = _near;
  89.     }
  90.  
  91.     //public bool _isZoomingInOrtho;
  92.  
  93.     void Awake()
  94.     {
  95.         if (_singleton != null)
  96.         {
  97.             Debug.LogError("Singleton instance already found for PerspectiveSwitcher");
  98.         }
  99.         _singleton = this;
  100.     }
  101.  
  102.     void Start()
  103.     {
  104.         _aspect = (float) Screen.width / (float) Screen.height;
  105.         _perspective = Matrix4x4.Perspective(_fov, _aspect, _near, _far);
  106.         _targetProjection = _perspective;
  107.  
  108.         camera.projectionMatrix = _perspective;
  109.         _orthoOn = false;
  110.  
  111.         _camX = transform.root.GetComponentInChildren<CamRotLeftRight>();
  112.         _camY = transform.root.GetComponentInChildren<CamRotUpDown>();
  113.         _camCollider = transform.root.GetComponentInChildren<CameraCollider>();
  114.         _camMove = transform.root.GetComponentInChildren<CamMovement>();
  115.  
  116.         if (_startInOrtho)
  117.         {
  118.             _orthoOn = true;
  119.  
  120.             _transitionSpeed = _transitionToOrthographicSpeed;
  121.             _camY.SkipTo(_cameraTiltWhenInIso);
  122.  
  123.             _camYLastY = _camY.CurrentY;
  124.             _camY.Locked = true;
  125.             _camCollider.Enabled = false;
  126.  
  127.             _camX.SetToOrthoMode(true);
  128.             _camMove.SetToOrthoMode(true);
  129.  
  130.             _targetProjection = Matrix4x4.Ortho(-_orthographicSize * _aspect, _orthographicSize * _aspect, -_orthographicSize, _orthographicSize, _orthoNear, _far);
  131.             _orthoCam.orthographicSize = _orthographicSize;
  132.  
  133.  
  134.             camera.projectionMatrix = _targetProjection;
  135.             ShowOrthoCam();
  136.         }
  137.     }
  138.  
  139.     public void SwitchToOrthographic()
  140.     {
  141.         if (!_orthoOn)
  142.         {
  143.             TogglePerspective();
  144.         }
  145.     }
  146.  
  147.     public void SwitchToPerspective()
  148.     {
  149.         if (_orthoOn)
  150.         {
  151.             TogglePerspective();
  152.         }
  153.     }
  154.  
  155.     public void TogglePerspective()
  156.     {
  157.         _orthoOn = !_orthoOn;
  158.         if (_orthoOn)
  159.         {
  160.             // to ortho
  161.             _transitionSpeed = _transitionToOrthographicSpeed;
  162.             _camY.MoveTo(_cameraTiltWhenInIso, _transitionSpeed); // put this in Update if you want real-time changing of tilt
  163.  
  164.             _camYLastY = _camY.CurrentY;
  165.             _camY.Locked = true;
  166.             _camCollider.Enabled = false;
  167.  
  168.             _camX.SetToOrthoMode(true);
  169.             _camMove.SetToOrthoMode(true);
  170.         }
  171.         else
  172.         {
  173.             // to perspective
  174.             _transitionSpeed = _transitionToPerspectiveSpeed;
  175.             _targetProjection = _perspective;
  176.             _camY.MoveTo(_camYLastY, _transitionSpeed);
  177.             _camY.Locked = false;
  178.             _camCollider.Enabled = true;
  179.  
  180.             _camX.SetToOrthoMode(false);
  181.             _camMove.SetToOrthoMode(false);
  182.  
  183.             ShowPerspectiveCam();
  184.         }
  185.     }
  186.  
  187.     void Update()
  188.     {
  189.         if (Input.GetButtonDown("EagleEye"))
  190.         {
  191.             TogglePerspective();
  192.         }
  193.  
  194.         if (_orthoOn)
  195.         {
  196.             _targetProjection = Matrix4x4.Ortho(-_orthographicSize * _aspect, _orthographicSize * _aspect, -_orthographicSize, _orthographicSize, _orthoNear, _far);
  197.             _orthoCam.orthographicSize = _orthographicSize;
  198.  
  199.             _orthoSwitchFinished = MatrixApproximately(camera.projectionMatrix, _targetProjection, 0.001f);
  200.  
  201.             if (_orthoSwitchFinished)
  202.             {
  203.                 ShowOrthoCam();
  204.             }
  205.         }
  206.         else
  207.         {
  208.             _orthoSwitchFinished = false;
  209.  
  210.             // only do this in editor or web build since window can be resized there, thus, a changing aspect ratio
  211.             _perspective = Matrix4x4.Perspective(_fov, _aspect, _near, _far);
  212.             _targetProjection = _perspective;
  213.         }
  214.  
  215.         _aspect = (float) Screen.width / (float) Screen.height;
  216.  
  217.         camera.projectionMatrix = MatrixLerp(camera.projectionMatrix, _targetProjection, Time.deltaTime * _transitionSpeed);
  218.     }
  219.  
  220.     public static Matrix4x4 MatrixLerp(Matrix4x4 from, Matrix4x4 to, float time)
  221.     {
  222.         Matrix4x4 ret = new Matrix4x4();
  223.         for (int i = 0; i < 16; i++)
  224.             ret[i] = Mathf.Lerp(from[i], to[i], time);
  225.         return ret;
  226.     }
  227.  
  228.     public static bool MatrixApproximately(Matrix4x4 a, Matrix4x4 b, float range)
  229.     {
  230.         return
  231.             Mathf.Abs(a[0] - b[0]) <= range &&
  232.             Mathf.Abs(a[1] - b[1]) <= range &&
  233.             Mathf.Abs(a[2] - b[2]) <= range &&
  234.             Mathf.Abs(a[3] - b[3]) <= range &&
  235.             Mathf.Abs(a[4] - b[4]) <= range &&
  236.             Mathf.Abs(a[5] - b[5]) <= range &&
  237.             Mathf.Abs(a[6] - b[6]) <= range &&
  238.             Mathf.Abs(a[7] - b[7]) <= range &&
  239.             Mathf.Abs(a[8] - b[8]) <= range &&
  240.             Mathf.Abs(a[9] - b[9]) <= range &&
  241.             Mathf.Abs(a[10] - b[10]) <= range &&
  242.             Mathf.Abs(a[11] - b[11]) <= range &&
  243.             Mathf.Abs(a[12] - b[12]) <= range &&
  244.             Mathf.Abs(a[13] - b[13]) <= range &&
  245.             Mathf.Abs(a[14] - b[14]) <= range &&
  246.             Mathf.Abs(a[15] - b[15]) <= range;
  247.     }
  248. }
  249.  
  250. } // namespace Victis.CameraSystem
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement