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 ;
}
}