Unity 相机跟随人物的几种方式

您所在的位置:网站首页 unity如何移动相机 Unity 相机跟随人物的几种方式

Unity 相机跟随人物的几种方式

#Unity 相机跟随人物的几种方式| 来源: 网络整理| 查看: 265

相机跟随一般写在生命周期LateUpdate中

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

最简单的就是 直接 把主相机作为Player角色的子物体,并自行固定好相机的位置和角度

优点:使用方便

缺点:使用不灵活,相机转动死板,体验不好,相机瞬间移动位置

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

设置一个空的GameObject,并且与Player的旋转和位置保持一致,然后将 主相机 设置成该GameObject的子对象。这种做法和方案 1 相似。

using UnityEngine; ///  /// 创建一个空物体, /// 此空物体的位置信息始终与主角的位置信息保持一致, /// 主相机或主角相机给此空物体当子物体 /// 当主角死亡时,空物体的位置信息更新为上一帧主角的位置信息 ///  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;     } }

(这种做法好处在于 当模拟角色死亡倒地的时候不会获取不到人物信息,如果采用方案 1 ,只能是重新创建一个相机,因为角色倒地的时候,子物体相机也会视角倒地,所以效率肯定方案 2 高)

优点:使用方便,适合大部分游戏模式

缺点:使用不灵活,相机转动死板(强制位移),体验不好

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

使用代码获取到一个相机的初始位置与人物之间的差值向量,在给相机赋值时再用这个差值向量与人物坐标求出相机的实时位置

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

优点:简单,方便,

缺点:无法一直跟随角色身后,适合固定视角游戏

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

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

不建议使用

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

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

代码实现相机跟随物体,可使用一个接口函数Vector3.SmoothDamp() 平滑阻尼 。  函数介绍:随着时间的推移,逐渐改变一个向量朝向预期的目标(有点类似受阻力减速运动) 在官方的手册里也有推荐用此函数 来实现 平滑的相机跟随

public static Vector3 SmoothDamp( Vector3 current, //当前物体位置 Vector3 target, //目标位置 ref Vector3 currentVelocity, //当前速度,这个值由你每次调用这个函数时被修改 //虽然使用ref关键字,不过函数运行时会自动修改 //一般传入参数值为0 float smoothTime, //到达目标的大约时间,较小的值将快速到达目标 float maxSpeed = Mathf.Infinity,//选择允许你限制的最大速度(默认为正无穷) float deltaTime = Time.deltaTime//自上次调用这个函数的时间(默认为Time.deltaTime) ); 6、代码控制,固定距离,跟随主角视角,平滑阻尼移动,看向主角 要使相机始终跟随主角身后,就要始终更新相机的位置在主角的Y轴后面,于是手动设置设置相机相对于主角的距离 using UnityEngine; public class CameraTest2 : MonoBehaviour{     public Transform player;    //角色位置信息     Vector3 off;                //相机目标点位置信息     Vector3 ve;                 //平滑阻尼的返回值     Quaternion angel;           //相机看向目标的旋转值     public float hight;         //相机的高度 public float foward;        //相机在角色后的距离     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);     } }

这样的注视,相机移动还是太快

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

using UnityEngine; public class CameraTest2 : MonoBehaviour{     public Transform player;    //角色位置信息     Vector3 off;                //相机目标点位置信息     public float speed;         //相机移动速度     Vector3 ve;                 //平滑阻尼的返回值     Quaternion angel;           //相机看向目标的旋转值     public float hight;         //相机的高度     public float foward;        //相机在角色后的距离     void LateUpdate(){         off = player.position + hight * player.up - foward * player.forward;         transform.position = Vector3.SmoothDamp(transform.position, off, ref ve, 0); //看向向量指向的方向         angel = Quaternion.LookRotation(player.position - off);         transform.rotation = Quaternion.Slerp(transform.rotation, angel, Time.deltaTime * speed);     } }

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

using UnityEngine; ///  /// 相机进行射线检测,如果检测不到主角, /// 就在起始点与结束点(主角头顶的一个点)之间寻找几个点, /// 直到找到可以看到主角的点 ///  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;         //相机目标位置,开始等于初始位置         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);     }     ///      /// 射线检测,相机是否能照到主角     ///      /// 计算射线发射的方向     /// 是否检测到     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、代码控制,固定距离,平滑的旋转相机,平滑阻尼移动,看向主角,有物体遮挡(方法二)

using UnityEngine; ///  /// 从主角发射射线检测相机的位置 /// 检测不到,就把相机移动到,射线的碰撞点的前面 ///  public class CameraTest2 : MonoBehaviour {     public Transform player;            //角色头部(设置空物体)位置信息     private Vector3 tagetPostion;       //相机看向的目标点     private Vector3 ve3;                //平滑阻尼的ref参数     Quaternion angel;                   //相机看向目标的旋转值     public float speed;                 //相机移动速度     public float upFloat;               //Y轴上升距离     public float backFloat;             //Z轴与主角的距离     void LateUpdate()     {         //记录相机初始位置         tagetPostion = player.position + player.up * upFloat - player.forward * backFloat;         [size=12.6667px]//刷新相机目标点的坐标         tagetPostion = Function(tagetPostion);         //主角的移动和看向         transform.position = Vector3.SmoothDamp(transform.position, tagetPostion, ref ve3, 0);         angel = Quaternion.LookRotation(player.position - tagetPostion);         transform.rotation = Quaternion.Slerp(transform.rotation, angel, speed);     }     ///      /// 射线检测,主角向后检测是否有相机跟随     ///      /// 用来计算射线发射的方向     /// 是否检测到     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、代码控制,固定距离,平滑的旋转相机,平滑阻尼移动,看向主角,有物体遮挡,结合手游中相机的旋转和复位

using UnityEngine; ///  /// 相机进行射线检测,如果检测不到主角, /// 就在起始点与结束点之间寻找几个点, /// 直到找到可以看到主角的点 /// 在游戏中玩家可以用鼠标控制相机的旋转 ///  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);     }     ///      /// 射线检测,相机是否能照到主角     ///      /// 计算射线发射的方向     /// 是否检测到     bool Function(Vector3 v3)     {         RaycastHit hit;         if (Physics.Raycast(v3, player.position - v3, out hit))         {             if (hit.collider.tag == "Player")             {                 return true;             }         }         return false;     } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3