Unity知识总结系列(二):相机跟随人物的几种方式

发布时间 2023-12-27 18:17:51作者: porter_代码工作者

相机跟随人物的几种方式

1、最简单,无代码,固定距离,固定视角

2、代码控制,固定距离,固定视角,对1进行改进

3、代码控制,固定距离,固定视角,直接移动,不会旋转

4、代码控制,固定距离,固定视角,插值移动(因为Update和LateUpdate刷新率不同,会有抖动现象,不建议使用)

5、代码控制,固定距离,固定视角,平滑阻尼移动

6、代码控制,固定距离,跟随主角视角,平滑阻尼移动,看向主角

7、代码控制,固定距离,平滑的旋转相机,平滑阻尼移动,看向主角

8、代码控制,固定距离,平滑的旋转相机,平滑阻尼移动,看向主角,考虑了有物体遮挡(方法一)

///   <summary>
///  相机进行射线检测,如果检测不到主角,
///  就在起始点与结束点 ( 主角头顶的一个点 ) 之间寻找几个点,
///  直到找到可以看到主角的点
///   </summary>
 
9、代码控制,固定距离,平滑的旋转相机,平滑阻尼移动,看向主角,考虑了有物体遮挡(方法二)
///   <summary>
///  从主角发射射线检测相机的位置
///  检测不到,就把相机移动到,射线的碰撞点的前面
///   </summary>
 
10、代码控制,固定距离,平滑的旋转相机,平滑阻尼移动,看向主角,有物体遮挡,结合手游中相机的旋转和复位
using  UnityEngine;
///   <summary>
///  相机进行射线检测,如果检测不到主角,
///  就在起始点与结束点之间寻找几个点,
///  直到找到可以看到主角的点
/// 在游戏中玩家可以用鼠标控制相机的旋转
///   </summary>
public   class   CameraTest2  :  MonoBehaviour
{
     public   Transform  player;     //角色位置信息
     Vector3 []  v3;         //相机自动找寻的位置点
     public   int  num;              //相机临时点的个数
     public   Vector3  start;        //相机开始时的位置
     public   Vector3  end;          //相机没有找到主角时的位置
     Vector3  tagetPostion;        //相机看向的目标点
     Vector3  ve3;                 //平滑阻尼的ref参数
     Quaternion  angel;            //相机看向目标的旋转值
     public   float  speed;          //相机移动速度
     void  Start ()
     {
         //外界赋值数组长度
        v3 =  new   Vector3 [ num ] ;
     }
     void  LateUpdate ()
     {
         //记录相机初始位置
        start = player.position + player.up * 2.0f - player.forward * 3.0f;
         //记录相机最终位置
        end = player.position + player.up * 5.0f;
         //鼠标控制相机的旋转
         if   ( Input .GetMouseButton ( 1 ) )
         {
             //记录相机的初始位置和旋转角度
             Vector3  pos = transform.position;
             Vector3  rot = transform.eulerAngles;
             //让相机绕着指定轴向旋转
            transform.RotateAround ( transform.position,  Vector3 .up,  Input .GetAxis ( "Mouse X" )  * 10 ) ;
            transform.RotateAround ( transform.position,  Vector3 .left, - Input .GetAxis ( "Mouse Y" )  * 10 ) ;
             //限制相机的绕X旋转的角度
             if   ( transform.eulerAngles.x < -60 || transform.eulerAngles.x > 60 )
             {
                transform.position = pos;
                transform.eulerAngles = rot;
             }
             return ;
         }
         //相机目标位置,开始等于初始位置
        tagetPostion = start;
        v3 [ 0 ]  = start;
        v3 [ num - 1 ]  = end;
         //动态获取相机的几个点
         for   ( int  i = 1; i < num; i++ )
         {
            v3 [ i ]  =  Vector3 .Lerp ( start, end, i / num ) ;
         }
         //判断相机在那个点可以看到主角
         for   ( int  i = 0; i < num; i++ )
         {
             if   ( Function ( v3 [ i ] ) )
             {
                tagetPostion = v3 [ i ] ;
                 break ;
             }
             if   ( i == num - 1 )
             {
                tagetPostion = end;
             }
         }
         //主角的移动和看向
        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>
     ///  射线检测,相机是否能照到主角
     ///   </summary>
     ///   <param name=" v3 "> 计算射线发射的方向 </param>
     ///   <returns> 是否检测到 </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 ;
     }
}

 


方便查阅:

资产: https://blog.csdn.net/qq_26270779/article/details/80227024