Advertisement
Guest User

Untitled

a guest
Jan 13th, 2014
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.11 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class HeroCamera : MonoBehaviour
  5. {
  6.     public LayerMask collisionLayers = -1;
  7.     public float heroHeight = 2.0f;
  8.     public float heroDistance = 5.0f;
  9.     public float minDistance = 2.0f;
  10.     public float maxDistance = 10.0f;
  11.     public int zoomRate = 200;
  12.     public float zoomDampening = 5.0f;
  13.     public float xSpeed = 200.0f;
  14.     public float ySpeed = 200.0f;
  15.     public bool invertMouseY = false;
  16.     public float rotationDampening = 3.0f;
  17.     public float offsetFromWall = 0.1f;
  18.     public float fpsCamDist = -0.15f;
  19.    
  20.     public bool useIdleOrbit = true;
  21.    
  22.     public enum CameraState
  23.     {
  24.         FirstPerson,
  25.         ThirdPerson,
  26.         Orbit
  27.     }
  28.     public CameraState camState = CameraState.ThirdPerson;
  29.    
  30.     public Transform cam = null;
  31.    
  32.     Transform hero;
  33.     public Transform headBone = null;
  34.     public int minAngleY = -50;
  35.     public int maxAngleY = 60;
  36.     float xAngl = 0.0f;
  37.     float yAngl = 0.0f;
  38.     float curDist;
  39.     float desDist;
  40.     float finalDist;
  41.    
  42.    
  43.     HeroCtrl hCtrl;
  44.    
  45.    
  46.     public CamInput camInput;
  47.     [System.Serializable]
  48.     public class CamInput
  49.     {
  50.         public float mX = 0;
  51.         public float mY = 0;
  52.         public float mSW = 0;
  53.         public bool doFPS = false;
  54.         public bool do3rdP = false;
  55.         public bool doOrbit = false;
  56.         public bool doLShift = false;
  57.     }
  58.    
  59.    
  60.     //=================================================================================================================o
  61.     void Start ()
  62.     {
  63.         hero = transform;
  64.        
  65.         hCtrl = GetComponent <HeroCtrl>() as HeroCtrl;
  66.        
  67.        
  68.         Vector3 angls = cam.eulerAngles;
  69.         xAngl = angls.x;
  70.         yAngl = angls.y;
  71.  
  72.         curDist = heroDistance;
  73.         desDist = heroDistance;
  74.         finalDist = heroDistance;
  75.                
  76.         //cam.camera.nearClipPlane = 0.01f;
  77.        
  78.         //Screen.lockCursor = true;
  79.         Screen.showCursor = false;
  80.        
  81.         // if no headbone search for it
  82.         if (headBone == null) {
  83.             Transform[] bones = GetComponentsInChildren <Transform>() as Transform[];
  84.             foreach (Transform t in bones) {
  85.                 if (t.name == "head")
  86.                     headBone = t;
  87.             }
  88.         }
  89.     }
  90.     //=================================================================================================================o
  91.     void IdleOrbit ()
  92.     {
  93.         if(hCtrl == null)
  94.             return;
  95.         if(hCtrl.v == 0 && hCtrl.h == 0)
  96.         {
  97.             hCtrl.canRotate = false;
  98.             camState = CameraState.Orbit;
  99.         }
  100.         else
  101.         {
  102.             if(camState == CameraState.Orbit)
  103.             {
  104.                 Quaternion r = Quaternion.Euler(0,cam.eulerAngles.y,0);
  105.                 hero.rotation = Quaternion.Lerp(hero.rotation, r, Time.deltaTime * 15);
  106.                 hCtrl.canRotate = true;
  107.                 camState = CameraState.ThirdPerson;
  108.             }
  109.         }
  110.     }
  111.     //=================================================================================================================o
  112.     void LateUpdate ()
  113.     {
  114.         // Cached Input
  115.         camInput.doFPS = false;
  116.         camInput.doOrbit = Input.GetKeyDown ("9");
  117.         camInput.do3rdP = Input.GetKeyDown ("0");
  118.         camInput.doLShift = Input.GetKeyDown (KeyCode.LeftShift);
  119.         camInput.mX = Input.GetAxis ("Mouse X");
  120.         camInput.mY = Input.GetAxis ("Mouse Y");
  121.         camInput.mSW = Input.GetAxis ("Mouse ScrollWheel");
  122.        
  123.        
  124.  
  125.         // 1,2,3 buttons for switching camera modi
  126.         if (camInput.doFPS)
  127.         {
  128.             // FirstPerson
  129.             cam.camera.fieldOfView = 80.0f;
  130.             camState = CameraState.FirstPerson;
  131.         }
  132.         else if (camInput.doOrbit)
  133.         {
  134.             // Orbit
  135.             cam.camera.fieldOfView = 70.0f;
  136.             camState = CameraState.Orbit;
  137.         }
  138.         else if (camInput.do3rdP)
  139.         {
  140.             // ThirdPerson
  141.             cam.camera.fieldOfView = 70.0f;
  142.             camState = CameraState.ThirdPerson;
  143.         }
  144.         else if(useIdleOrbit)
  145.         {
  146.             IdleOrbit();
  147.         }
  148.        
  149.        
  150.        
  151.         // Camera states
  152.         switch (camState)
  153.         {
  154.         case CameraState.FirstPerson:
  155.             FirstPerson();
  156.             break;
  157.         case CameraState.ThirdPerson:
  158.             ThirdPerson();
  159.             break;
  160.         case CameraState.Orbit:
  161.             Orbit();
  162.             break;
  163.         }
  164.     }
  165.     //=================================================================================================================o
  166.     void FirstPerson ()
  167.     {
  168.         // Horizontal
  169.         xAngl = hero.eulerAngles.y;
  170.         // Vertical
  171.         yAngl = ClampAngle (yAngl, minAngleY /1.5f, maxAngleY /1.1f);
  172.        
  173.         // Desired distance
  174.         desDist = fpsCamDist;
  175.         // Camera rotation
  176.         Quaternion camRot = Quaternion.Euler (yAngl, xAngl, 0);
  177.         // Camera position
  178.         Vector3 camPos = headBone.position - (cam.forward * desDist) - (cam.up * -heroHeight /4);
  179.        
  180.         // Apply Y-mouse axis
  181.         if(invertMouseY)
  182.             yAngl += Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
  183.         else
  184.             yAngl -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
  185.        
  186.         // Apply position and rotation
  187.         cam.rotation = camRot;
  188.         cam.position = camPos;
  189.     }
  190.     //=================================================================================================================o
  191.     void ThirdPerson ()
  192.     {
  193.         // Desired distance via mouse wheel
  194.         desDist -= camInput.mSW * Time.deltaTime * zoomRate * Mathf.Abs (desDist);
  195.         desDist = Mathf.Clamp (desDist, minDistance, maxDistance);
  196.         finalDist = desDist;
  197.        
  198.         // Horizontal smooth rotation
  199.         xAngl = Mathf.LerpAngle (cam.eulerAngles.y, hero.eulerAngles.y, rotationDampening * Time.deltaTime);
  200.         // Vertical angle limitation
  201.         yAngl = ClampAngle (yAngl, minAngleY, maxAngleY);
  202.         // Camera rotation
  203.         Quaternion camRot = Quaternion.Euler (yAngl, xAngl, 0);
  204.         // Camera height
  205.         Vector3 headPos = new Vector3 (0, -heroHeight /1.2f, 0);
  206.         // Camera position
  207.         Vector3 camPos = hero.position - (camRot * Vector3.forward * desDist + headPos);
  208.        
  209.         // Recalculate hero position
  210.         Vector3 trueHeroPos = new Vector3 (hero.position.x, hero.position.y + heroHeight, hero.position.z);
  211.        
  212.         // Check for collision with Linecast
  213.         RaycastHit hit;
  214.         bool isOk = false;
  215.         if ( Physics.Linecast (trueHeroPos, camPos - Vector3.up + Vector3.forward, out hit, collisionLayers.value)) // slightly behind and below the camera
  216.         {
  217.             // Final distance
  218.             finalDist = Vector3.Distance (trueHeroPos, hit.point) - offsetFromWall;
  219.             isOk = true;
  220.         }
  221.        
  222.         // Lerp current distance if not corrected
  223.         if ( !isOk || ( finalDist > curDist ) )
  224.             curDist = Mathf.Lerp (curDist, finalDist, Time.deltaTime * zoomDampening);
  225.         else
  226.             curDist = finalDist;
  227.        
  228.         // Clamp current distance
  229.         //curDist = Mathf.Clamp (curDist, minDistance, maxDistance);
  230.        
  231.         // Recalculate camera position
  232.         camPos = hero.position - (camRot * Vector3.forward * curDist + headPos);
  233.        
  234.         // Left shift = no y rotation
  235.         if(!camInput.doLShift)
  236.         {
  237.             // Apply Y-mouse axis
  238.             if(invertMouseY)
  239.                 yAngl += Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
  240.             else
  241.                 yAngl -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
  242.         }
  243.        
  244.        
  245.         // Apply position and rotation
  246.         cam.rotation = camRot;
  247.         cam.position = camPos;
  248.     }
  249.     //=================================================================================================================o
  250.     void Orbit ()
  251.     {
  252.         // Desired distance via mouse wheel
  253.         desDist -= camInput.mSW * Time.deltaTime * zoomRate * Mathf.Abs (desDist);
  254.         desDist = Mathf.Clamp (desDist, minDistance, maxDistance);
  255.         finalDist = desDist;
  256.        
  257.         // Horizontal smooth rotation
  258.         xAngl += camInput.mX * xSpeed * 0.02f;
  259.         // Vertical angle limitation
  260.         yAngl = ClampAngle (yAngl, minAngleY, maxAngleY);
  261.        
  262.         // Camera rotation
  263.         Quaternion camRot = Quaternion.Euler (yAngl, xAngl, 0);
  264.         // Camera height
  265.         Vector3 headPos = new Vector3 (0, -heroHeight /1.2f, 0);
  266.         // Camera position
  267.         Vector3 camPos = hero.position - (camRot * Vector3.forward * desDist + headPos);
  268.        
  269.         // Recalculate hero position
  270.         Vector3 trueHeroPos = new Vector3 (hero.position.x, hero.position.y + heroHeight, hero.position.z);
  271.        
  272.         // Check if there is something between camera and character
  273.         RaycastHit hit;
  274.         bool isOk = false;
  275.         if ( Physics.Linecast (trueHeroPos, camPos, out hit, collisionLayers.value))
  276.         {
  277.             // Final distance
  278.             finalDist = Vector3.Distance (trueHeroPos, hit.point) - offsetFromWall;
  279.             isOk = true;
  280.         }
  281.        
  282.         // Lerp current distance if not corrected
  283.         if ( !isOk || ( finalDist > curDist ) )
  284.             curDist = Mathf.Lerp (curDist, finalDist, Time.deltaTime * zoomDampening);
  285.         else
  286.             curDist = finalDist;
  287.        
  288.         // Clamp current distance
  289.         //curDist = Mathf.Clamp (curDist, minDistance, maxDistance);
  290.        
  291.         // Recalculate camera position
  292.         camPos = hero.position - (camRot * Vector3.forward * curDist + headPos);
  293.        
  294.         // Left shift = no y rotation
  295.         if(!camInput.doLShift)
  296.         {
  297.             // Apply Y-mouse axis
  298.             if(invertMouseY)
  299.                 yAngl += Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
  300.             else
  301.                 yAngl -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
  302.         }
  303.  
  304.        
  305.         // Apply position and rotation
  306.         cam.rotation = camRot;
  307.         cam.position = camPos;
  308.     }
  309.     //=================================================================================================================o
  310.    
  311.     // Clamp angle at 360deg
  312.     static float ClampAngle ( float angle, float min, float max )
  313.     {
  314.         if (angle < -360)
  315.             angle += 360;
  316.         if (angle > 360)
  317.             angle -= 360;
  318.         return Mathf.Clamp (angle, min, max);
  319.     }
  320.     //=================================================================================================================o
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement