Search Unity

[Code] Camera Control: Smooth Round-LookAt-Zoom to GameObject

Discussion in 'Community Learning & Teaching' started by IsGreen, Apr 20, 2015.

  1. IsGreen

    IsGreen

    Joined:
    Jan 17, 2014
    Posts:
    206
    Camera control, a fairly common thing in all games.

    Here let the script to make turns around GameObject with zoom and smooth effects.

    You can configure many parameters:

    - Angle ranges.
    - Camera distance
    - Smooth Speed.
    - Rotation Speed.

    In addition, it runs in Edit Mode to properly configure the camera (except speeds, which only work during the Play Mode).

    Only need attach the script to GameObject target.



    Download link.

    Code (CSharp):
    1. namespace UnitySpain.Kaito.Camera{
    2.  
    3.     using UnityEngine;
    4.  
    5.  
    6.     [ExecuteInEditMode]
    7.     public class RoundLookAt : MonoBehaviour {
    8.  
    9.         [System.Serializable]
    10.         public class SmoothSettings{
    11.  
    12.             [System.Serializable]
    13.             public class Time{
    14.  
    15.                 public float positionTime = 0.4f;
    16.                 public float zoomTime     = 0.4f;
    17.                 public float angleXTime   = 0.4f;
    18.                 public float angleYTime   = 0.4f;
    19.  
    20.             }
    21.  
    22.             [System.Serializable]
    23.             public class Velocity{
    24.  
    25.                 public float zoomVelocity   = 8f;
    26.                 public float angleXVelocity = 0.75f;
    27.                 public float angleYVelocity = 2.5f;
    28.  
    29.             }
    30.  
    31.             [System.Serializable]
    32.             public class Range{
    33.  
    34.                 public Vector2 zoomRange   = new Vector2(1.5f,20f);
    35.                 public Vector2 angleXRange = new Vector2(-89f,89f);
    36.                 public Vector2 angleYRange = new Vector2(-1e7f,1e7f);
    37.  
    38.             }
    39.  
    40.             public Time time = new Time();
    41.             public Velocity velocity = new Velocity();
    42.             public Range range = new Range();
    43.  
    44.         }
    45.  
    46.         [System.Serializable]
    47.         public class OffSet{
    48.  
    49.             [System.Serializable]
    50.             public class MinMaxVector3{
    51.  
    52.                 public Vector3 toMinDistance = Vector3.zero;
    53.                 public Vector3 toMaxDistance = Vector3.zero;
    54.  
    55.             }
    56.  
    57.             public MinMaxVector3 offSetLookAt   = new MinMaxVector3();
    58.             public MinMaxVector3 offSetPosition = new MinMaxVector3();
    59.  
    60.         }
    61.  
    62.         [Header("Camera Settings")]
    63.         [Range(-89,89f)]
    64.         public float angleX = 0f;
    65.         [Range(-360f,360f)]
    66.         public float angleY = 0f;
    67.         [Range(0f,1f)]
    68.         public float distance = 0.5f;
    69.         public OffSet offSet = new OffSet();
    70.  
    71.         [Space(4f)]
    72.         [Header("Smooth Settings")]
    73.         public SmoothSettings smoothSettings = new SmoothSettings();
    74.  
    75.  
    76.         private Transform target , cameraMain;
    77.         private Vector3 pivot , lastEulerAngle , velocityPivot = Vector3.zero;
    78.         private float zoom       = 0f , velocityAngleX = 0f , velocityAngleY = 0f, velocityZoom = 0f,
    79.                       smoothZoom = 0f , smoothAngleX   = 0f , smoothAngleY   = 0f;
    80.  
    81.         static Vector3 forward = Vector3.forward;
    82.  
    83.  
    84.  
    85.         void Start(){
    86.  
    87.             if(Camera.main == null) {
    88.  
    89.                 Debug.LogError(this.name + " - RoundLookAt: Main Camera not found");
    90.                 if(Application.isPlaying) Destroy(this); else DestroyImmediate(this);
    91.                 return;
    92.  
    93.             }
    94.  
    95.             this.target         = this.transform;
    96.             this.pivot          = this.target.position;
    97.             this.lastEulerAngle = this.target.rotation.eulerAngles;
    98.             this.cameraMain     = Camera.main.transform;
    99.  
    100.             this.smoothZoom   = this.zoom   = this.smoothSettings.range.zoomRange.x + (this.smoothSettings.range.zoomRange.y - this.smoothSettings.range.zoomRange.x) * this.distance;
    101.             this.smoothAngleX = this.angleX;
    102.             this.smoothAngleY = this.angleY;
    103.  
    104.         }
    105.  
    106.         void CheckInspector(){
    107.  
    108.             if(this.smoothSettings.range.zoomRange.x   > this.smoothSettings.range.zoomRange.y)  { float temp = this.smoothSettings.range.zoomRange.x;   this.smoothSettings.range.zoomRange.x   = this.smoothSettings.range.zoomRange.y;   this.smoothSettings.range.zoomRange.y   = temp; }
    109.             if(this.smoothSettings.range.angleXRange.x > this.smoothSettings.range.angleXRange.y){ float temp = this.smoothSettings.range.angleXRange.x; this.smoothSettings.range.angleXRange.x = this.smoothSettings.range.angleXRange.y; this.smoothSettings.range.angleXRange.y = temp; }
    110.             if(this.smoothSettings.range.angleYRange.x > this.smoothSettings.range.angleYRange.y){ float temp = this.smoothSettings.range.angleYRange.x; this.smoothSettings.range.angleYRange.x = this.smoothSettings.range.angleYRange.y; this.smoothSettings.range.angleYRange.y = temp; }
    111.            
    112.             this.smoothSettings.range.angleXRange.x = Mathf.Clamp( this.smoothSettings.range.angleXRange.x , -1e7f , 1e7f );
    113.             this.smoothSettings.range.angleXRange.y = Mathf.Clamp( this.smoothSettings.range.angleXRange.y , -1e7f , 1e7f );
    114.             this.smoothSettings.range.angleYRange.x = Mathf.Clamp( this.smoothSettings.range.angleYRange.x , -1e7f , 1e7f );
    115.             this.smoothSettings.range.angleYRange.y = Mathf.Clamp( this.smoothSettings.range.angleYRange.y , -1e7f , 1e7f );
    116.  
    117.         }
    118.  
    119.         void SetCamera(){
    120.  
    121.             float t              = ( this.smoothZoom - this.smoothSettings.range.zoomRange.x ) / ( this.smoothSettings.range.zoomRange.y - this.smoothSettings.range.zoomRange.x );
    122.             Vector3 lerpPosition = this.target.rotation * Vector3.Lerp(this.offSet.offSetPosition.toMinDistance , this.offSet.offSetPosition.toMaxDistance , t );
    123.             Vector3 lerpLookAt   = this.target.rotation * Vector3.Lerp(this.offSet.offSetLookAt.toMinDistance   , this.offSet.offSetLookAt.toMaxDistance   , t );
    124.  
    125.             this.cameraMain.position = Matrix4x4.TRS(this.pivot, Quaternion.Euler( this.smoothAngleX , this.smoothAngleY , 0f ) , Vector3.one * this.smoothZoom ).MultiplyPoint3x4( forward )
    126.                                        + lerpPosition;
    127.  
    128.             this.cameraMain.LookAt( this.target.position + lerpLookAt );
    129.  
    130.         }
    131.  
    132.         void Update () {
    133.  
    134.             Vector3 eulerTarget = this.target.eulerAngles;
    135.  
    136.             #if UNITY_EDITOR
    137.            
    138.             if(!Application.isPlaying){
    139.  
    140.                 CheckInspector();
    141.                 this.pivot        = this.target.position;
    142.                 this.smoothZoom   = this.smoothSettings.range.zoomRange.x + ( this.smoothSettings.range.zoomRange.y - this.smoothSettings.range.zoomRange.x ) * this.distance;
    143.                 this.smoothAngleX = this.angleX = Mathf.Clamp( this.angleX + eulerTarget.x, this.smoothSettings.range.angleXRange.x + eulerTarget.x, this.smoothSettings.range.angleXRange.y + eulerTarget.x );
    144.                 this.smoothAngleY = this.angleY = Mathf.Clamp( this.angleY + eulerTarget.y, this.smoothSettings.range.angleYRange.x + eulerTarget.y, this.smoothSettings.range.angleYRange.y + eulerTarget.y );
    145.    
    146.                 this.SetCamera();
    147.  
    148.                 return;
    149.                
    150.             }
    151.            
    152.             #endif
    153.  
    154.             Vector3 difference  = eulerTarget - this.lastEulerAngle;
    155.             this.lastEulerAngle = eulerTarget;
    156.                        
    157.             this.zoom   = Mathf.Clamp( this.zoom  - Input.GetAxis("Mouse ScrollWheel")       * this.smoothSettings.velocity.zoomVelocity   , this.smoothSettings.range.zoomRange.x                   , this.smoothSettings.range.zoomRange.y                   );
    158.             this.angleX = Mathf.Clamp( this.angleX + difference.x - Input.GetAxis("Mouse Y") * this.smoothSettings.velocity.angleXVelocity , this.smoothSettings.range.angleXRange.x + eulerTarget.x , this.smoothSettings.range.angleXRange.y + eulerTarget.x );
    159.             this.angleY = Mathf.Clamp( this.angleY + difference.y + Input.GetAxis("Mouse X") * this.smoothSettings.velocity.angleYVelocity , this.smoothSettings.range.angleYRange.x + eulerTarget.y , this.smoothSettings.range.angleYRange.y + eulerTarget.y );
    160.    
    161.             this.smoothZoom   = Mathf.SmoothDampAngle( this.smoothZoom   , this.zoom   , ref this.velocityZoom     , this.smoothSettings.time.zoomTime   );
    162.             this.smoothAngleX = Mathf.SmoothDampAngle( this.smoothAngleX , this.angleX , ref this.velocityAngleX   , this.smoothSettings.time.angleXTime );
    163.             this.smoothAngleY = Mathf.SmoothDampAngle( this.smoothAngleY , this.angleY , ref this.velocityAngleY   , this.smoothSettings.time.angleYTime );
    164.  
    165.             this.pivot = Vector3.SmoothDamp(this.pivot, this.target.position, ref velocityPivot, this.smoothSettings.time.positionTime);
    166.  
    167.             this.SetCamera();
    168.  
    169.         }
    170.  
    171.     }
    172.  
    173. }
     
    John-G and theANMATOR2b like this.
  2. John-G

    John-G

    Joined:
    Mar 21, 2013
    Posts:
    1,122
    Very nice Script, thanks for sharing. :)