Unity camera follow detailed explanation

Unity knowledge summary series (2): Several ways for the camera to follow the characters 
http://www.manew.com/thread-114711-1-1.html 

(Source: -[Game Bull]-ar augmented reality, virtual reality, unity3d, unity3d tutorial download preferred u3d, unity3d official website)

Camera follow is generally written in the life cycle LateUpdate

1. The simplest, no code, fixed distance, fixed viewing angle

The easiest way is to directly use the main camera as a sub-object of the Player character, and fix the position and angle of the camera by itself

Advantages: easy to use

Disadvantages: inflexible use, rigid camera rotation, bad experience, camera moves position instantly

2. Code control, fixed distance, fixed viewing angle, improved on 1

Set an empty GameObject with the same rotation and position as the Player, and then set the main camera as a child of the GameObject. This approach is similar to option 1.

using  UnityEngine;

///   <summary>

/// Create an empty object,

/// The position information of this empty object is always consistent with the position information of the protagonist,

/// The main camera or the protagonist camera gives this empty object as a child object

/// When the protagonist dies, the position information of the empty object is updated to the position information of the protagonist in the previous frame

///   </summary>

public   class   CameraTest  :  MonoBehaviour {

     public   Transform  player;

     Vector3  tempPostion;

Quaternion tempRotation;

     void  Update (){

         if   ( player ){

            transform.position = player.position;

            transform.rotation = player.rotation;

         }

         else {

            transform.position = tempPostion;

            transform.rotation = tempRotation;

         }

        tempPostion = player.position;

        tempRotation = player.rotation;

     }


(The advantage of this approach is that when the simulated character falls to the ground, the character information will not be lost. If you use option 1, you can only recreate a camera, because when the character falls to the ground, the sub-object camera will also have an inverted perspective ground, so the efficiency must be high in scheme 2)

Advantages: easy to use, suitable for most game modes

Disadvantages: inflexible use, rigid camera rotation (forced displacement), bad experience

3. Code control, fixed distance, fixed viewing angle, direct movement, no rotation

Use the code to obtain the difference vector between the initial position of the camera and the person, and then use the difference vector and the person coordinates to find the real-time position of the camera when assigning a value to the camera

using  UnityEngine;

public   class   CameraTest2  :  MonoBehaviour {

     public   Transform  player;

Vector3 distance;

     void  Start (){

        distance = transform.position - player.position;

     }

     void  LateUpdate (){

        transform.position = player.position + distance;

     }

}

Advantages: simple, convenient,

Disadvantage: unable to follow the character all the time, suitable for fixed-view games

4. Code control, fixed distance, fixed viewing angle, interpolation movement (because the update rate of Update and LateUpdate are different, there will be jitter)

using  UnityEngine;

public   class   CameraTest2  :  MonoBehaviour {

     public   Transform  player;

     Vector3  distance;

     public   float  speed;

     void  Start (){

        distance = transform.position - player.position;

     }

     void  LateUpdate (){

        transform.position =  Vector3 .Lerp ( transform.position, player.position + distance,  Time .deltaTime * speed ) ;

     }

}

Not recommended for use

5. Code control, fixed distance, fixed viewing angle, smooth damped movement

using  UnityEngine;

public   class   CameraTest2  :  MonoBehaviour {

     public   Transform  player;

     Vector3  distance;

     public   float  speed;

Vector3 ve;

     void  Start (){

        distance = transform.position - player.position;

     }

     void  LateUpdate (){

        transform.position =  Vector3 .SmoothDamp ( transform.position, player.position + distance,  ref  ve, 0 ) ;

     }

}

The code realizes that the camera follows the object, and an interface function Vector3.SmoothDamp() can be used for smooth damping.   
Function introduction: As time goes by, gradually change a vector towards the expected target (somewhat similar to resistance deceleration movement). This function is also recommended in the official manual to achieve smooth camera follow

public   static  Vector3 SmoothDamp(

Vector3 current, //current object position

Vector3 target, //target position

ref Vector3 currentVelocity, //current velocity, this value is modified every time you call this function

//Although the ref keyword is used, it will be automatically modified when the function is running

//The general incoming parameter value is 0

float smoothTime, //Approximate time to reach the target, a smaller value will reach the target quickly

float maxSpeed ​​= Mathf.Infinity,//Choose the maximum speed that allows you to limit (the default is positive infinity)

float deltaTime = Time.deltaTime//Time since last call to this function (default is Time.deltaTime) );

6. Code control, fixed distance, following the perspective of the protagonist, smooth damped movement, looking at the protagonist

To make the camera always follow the protagonist, it is necessary to always update the position of the camera to be behind the Y axis of the protagonist, so manually set the distance between the camera and the protagonist

using  UnityEngine;

public   class   CameraTest2  :  MonoBehaviour {

     public Transform player; //character position information

     Vector3 off; //Camera target point position information

     Vector3 ve; // return value of smooth damping

     Quaternion angel; //The rotation value of the camera looking at the target

     public float hight; //The height of the camera

public float foward; //The distance of the camera behind the character

     void  LateUpdate (){

        off = player.position + hight * player.up - foward * player.forward;

        transform.position =  Vector3 .SmoothDamp ( transform.position, off,  ref  ve, 0 ) ;

        transform.LookAt ( player.position ) ;

     }

}

Such a gaze, the camera is still moving too fast

7. Code control, fixed distance, smooth camera rotation, smooth damped movement, looking at the protagonist

using  UnityEngine;

public   class   CameraTest2  :  MonoBehaviour {

     public Transform player; //character position information

     Vector3 off; //Camera target point position information

     public float speed; //Camera movement speed

     Vector3 ve; // return value of smooth damping

     Quaternion angel; //The rotation value of the camera looking at the target

     public float hight; //The height of the camera

     public float foward; //The distance of the camera behind the character

     void  LateUpdate (){

        off = player.position + hight * player.up - foward * player.forward;

        transform.position =  Vector3 .SmoothDamp ( transform.position, off,  ref  ve, 0 ) ;

// look in the direction the vector is pointing

        angel =  Quaternion .LookRotation ( player.position - off ) ;

        transform.rotation =  Quaternion .Slerp ( transform.rotation, angel,  Time .deltaTime * speed ) ;

     }

}

8. Code control, fixed distance, smooth camera rotation, smooth damped movement, looking at the protagonist, with object occlusion (method 1)

using  UnityEngine;

///   <summary>

/// The camera performs ray detection, if the protagonist cannot be detected,

/// Just look for a few points between the starting point and the ending point (a point above the protagonist's head),

/// Until we find a point where we can see the main character

///   </summary>

public   class   CameraTest2  :  MonoBehaviour

{

     public Transform player; //character position information

     Vector3 [] v3; //The location point that the camera automatically finds

     public int num; //Number of camera temporary points

     public Vector3 start; //The position of the camera at the beginning

     public Vector3 end; //The camera does not find the position of the protagonist

     Vector3 tagetPostion; //The target point that the camera looks at

     Vector3 ve3; //ref parameter of smooth damping

     Quaternion angel; //The rotation value of the camera looking at the target

     public float speed; //Camera movement speed

     void  Start ()

     {

         //External assignment array length

        v3 =  new   Vector3 [ num ] ;

     }

     void  LateUpdate ()

     {

         //Record the initial position of the camera

        start = player.position + player.up * 2.0f - player.forward * 3.0f;

         //Record the final position of the camera

        end = player.position + player.up * 5.0f;

         //Camera target position, start equal to initial position

        tagetPostion = start;

        v3 [ 0 ] = start;

        v3 [ num - 1 ]  = end;

         //Get several points of the camera dynamically

         for   ( int  i = 1; i < num; i++ )

         {

            v3 [ i ]  =  Vector3 .Lerp ( start, end, i / num ) ;

         }

         //Determine at which point the camera can see the protagonist

         for   ( int  i = 0; i < num; i++ )

         {

             if   ( Function ( v3 [ i ] ) )

             {

                tagetPostion = v3 [ i ] ;

                 break ;

             }

             if   ( i == num - 1 )

             {

                tagetPostion = end;

             }

         }

         //The movement and look of the main character

        transform.position =  Vector3 .SmoothDamp ( transform.position, tagetPostion,  ref  ve3, 0 ) ;

        angel =  Quaternion .LookRotation ( player.position - tagetPostion ) ;

        transform.rotation =  Quaternion .Slerp ( transform.rotation, angel, speed ) ;

     }

     ///   <summary>

     /// Ray detection, whether the camera can see the protagonist

     ///   </summary>

     /// <param name=" v3 "> Calculate the direction of ray emission </param>

     /// <returns> Whether it is detected </returns>

     bool  Function ( Vector3  v3 )

     {

         RaycastHit  hit;

         if   ( Physics .Raycast ( v3, player.position - v3,  out  hit ) )

         {

             if   ( hit.collider.tag ==  "Player" )

             {

                 return   true ;

             }

         }

         return   false ;

     }

}

9. Code control, fixed distance, smooth camera rotation, smooth damped movement, looking at the protagonist, with object occlusion (method 2)

using  UnityEngine;

///   <summary>

/// Emitting rays from the protagonist to detect the position of the camera

/// If it cannot be detected, move the camera to the front of the collision point of the ray

///   </summary>

public   class   CameraTest2  :  MonoBehaviour

{

     public Transform player; // position information of character head (set empty object)

     private Vector3 tagetPostion; //The target point that the camera looks at

     private Vector3 ve3; //ref parameter of smooth damping

     Quaternion angel; //The rotation value of the camera looking at the target

     public float speed; //Camera movement speed

     public float upFloat; //Y-axis rising distance

     public float backFloat; //The distance between the Z axis and the protagonist

     void  LateUpdate ()

     {

         //Record the initial position of the camera

        tagetPostion = player.position + player.up * upFloat - player.forward * backFloat;

         [size=12.6667px]//Refresh the coordinates of the camera target point

        tagetPostion = Function ( tagetPostion ) ;

         //The movement and look of the main character

        transform.position =  Vector3 .SmoothDamp ( transform.position, tagetPostion,  ref  ve3, 0 ) ;

        angel =  Quaternion .LookRotation ( player.position - tagetPostion ) ;

        transform.rotation =  Quaternion .Slerp ( transform.rotation, angel, speed ) ;

     }

     ///   <summary>

     /// Ray detection, the protagonist checks backwards whether there is a camera following

     ///   </summary>

     /// <param name=" v3 ">Used to calculate the direction of ray emission </param>

     /// <returns> Whether it is detected </returns>

     Vector3  Function ( Vector3  v3 )

     {

         RaycastHit  hit;

         if   ( Physics .Raycast ( player.position, v3 - player.position,  out  hit, 5.0f ) )

         {

             if   ( hit.collider.tag !=  "MainCamera" )

             {

                v3 = hit.point + transform.forward * 0.5f;

             }

         }

         return  v3;

     }

}

10. Code control, fixed distance, smooth camera rotation, smooth damped movement, looking at the protagonist, there is an object occlusion, combined with the rotation and reset of the camera in the mobile game

using  UnityEngine;

///   <summary>

/// The camera performs ray detection, if the protagonist cannot be detected,

/// Find several points between the start point and the end point,

/// Until we find a point where we can see the main character

/// In the game, the player can use the mouse to control the rotation of the camera

///   </summary>

public   class   CameraTest2  :  MonoBehaviour

{

     public Transform player; //character position information

     Vector3 [] v3; //The location point that the camera automatically finds

     public int num; //Number of camera temporary points

     public Vector3 start; //The position of the camera at the beginning

     public Vector3 end; //The camera does not find the position of the protagonist

     Vector3 tagetPostion; //The target point that the camera looks at

     Vector3 ve3; //ref parameter of smooth damping

     Quaternion angel; //The rotation value of the camera looking at the target

     public float speed; //Camera movement speed

     void  Start ()

     {

         //External assignment array length

        v3 =  new   Vector3 [ num ] ;

     }

     void  LateUpdate ()

     {

         //Record the initial position of the camera

        start = player.position + player.up * 2.0f - player.forward * 3.0f;

         //Record the final position of the camera

        end = player.position + player.up * 5.0f;

         //Mouse controls the rotation of the camera

         if   ( Input .GetMouseButton ( 1 ) )

         {

             //Record the initial position and rotation angle of the camera

             Vector3  pos = transform.position;

             Vector3  rot = transform.eulerAngles;

             // Let the camera rotate around the specified axis

            transform.RotateAround ( transform.position,  Vector3 .up,  Input .GetAxis ( "Mouse X" )  * 10 ) ;

            transform.RotateAround ( transform.position,  Vector3 .left, - Input .GetAxis ( "Mouse Y" )  * 10 ) ;

             //Limit the camera's rotation angle around X

             if   ( transform.eulerAngles.x < -60 || transform.eulerAngles.x > 60 )

             {

                transform.position = pos;

                transform.eulerAngles = rot;

             }

             return ;

         }

         //Camera target position, start equal to initial position

        tagetPostion = start;

        v3 [ 0 ] = start;

        v3 [ num - 1 ]  = end;

         //Get several points of the camera dynamically

         for   ( int  i = 1; i < num; i++ )

         {

            v3 [ i ]  =  Vector3 .Lerp ( start, end, i / num ) ;

         }

         //Determine at which point the camera can see the protagonist

         for   ( int  i = 0; i < num; i++ )

         {

             if   ( Function ( v3 [ i ] ) )

             {

                tagetPostion = v3 [ i ] ;

                 break ;

             }

             if   ( i == num - 1 )

             {

                tagetPostion = end;

             }

         }

         //The movement and look of the main character

        transform.position =  Vector3 .SmoothDamp ( transform.position, tagetPostion,  ref  ve3, 0 ) ;

        angel =  Quaternion .LookRotation ( player.position - tagetPostion ) ;

        transform.rotation =  Quaternion .Slerp ( transform.rotation, angel, speed ) ;

     }

     ///   <summary>

     /// Ray detection, whether the camera can see the protagonist

     ///   </summary>

     /// <param name=" v3 "> Calculate the direction of ray emission </param>

     /// <returns> Whether it is detected </returns>

     bool  Function ( Vector3  v3 )

     {

         RaycastHit  hit;

         if   ( Physics .Raycast ( v3, player.position - v3,  out  hit ) )

         {

             if   ( hit.collider.tag ==  "Player" )

             {

                 return   true ;

             }

         }

         return   false ;

     }

}

Guess you like

Origin blog.csdn.net/Star_MengMeng/article/details/122893945