SpringDragon

导航

 

在Unity3D中,先调整MainCamera在场景中的位置,然后把脚本挂到MainCamera上,摄像机跟随分为简单的摄像机跟随和高级摄像机跟随。

  简单摄像机跟随:
public class CameraFollow:MonoBehaviour()
{
    //设置摄像机跟随速度
    private float moveSpeed = 3f;
  //设置摄像机旋转速度
  private float turnSpeed = 10f;
//设置摄像机跟随的物体 private Transform target; //定义方向向量 private Vector3 dir; void Awake(){ //获取物体 target = GameObject.FindWithTag(Tags.Player).transform; } void Start(){ //获取方向向量 dir = transform.position - target.position; } void Update(){ //跟随目标 transform.position = Vector3.Lerp(transform.position, target.position+dir, moveSpeed * Time.deltaTime);
     //摄像机旋转
     transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(dir), turnSpeed * Time.deltaTime); } }
  在摄像机的简单跟随中,应用的场景中如果有一些障碍物,target在障碍物的后面会在游戏视图中看不到target,因此在大多数的场景中不适用。
高级摄像机跟随:在跟随的目标移动到障碍物后面的时候,调整摄像机的位置,达到看到目标的目的;原理:当target走到障碍物后面,用RaycastHit射线检测摄像机照到的物体是否是target,如果不是,设置档位,依次慢慢移动摄像机,直到照到target为止,所以可以在设定档位的时候,最后一个档位为target的正上方;当target移动到障碍物外面的时候,还原为以前的视角。
  高级摄像机跟随代码如下:
public class Camera : MonoBehaviour{
    //设置摄像机的移动速度
    private float moveSpeed = 3f;
    //设置摄像机的旋转速度
    private float turnSpeed = 10f;
    //摄像机跟随目标
    private Transform target;
    //方向向量
    private Vector3 dir;
    //设置档位
    private int gears = 5;
    //射线碰撞检测器
    privatr RaycastHit hit;
    void Awake(){
        //照到摄像机跟随目标
        target = GameObject.FindWithTag(Tags.Player).transform;
    }
    void Start(){
        dir = transform.position - target.position;
    }
    void Update(){
        //起始坐标
        Vector3 beginPos = target.position + dir;
        //摄像机的投影向量
        Vector3 projectDir = Vector3 Project(dir, Vector3.up);
        //计算头顶摄像机与target之间的距离
        float distance = projectDir.mignitude;
        //target头顶坐标
        Vector3 endPos = target.position + Vector3.up * distance;
        //所有档位
        Vector3[] allPos = new Vector3[gears];
        //起点
        allPos[0] = beginPos;
        //终点
        allPos[allPos.Length - 1] = endPos;
        //填充中间点
        for(int i = 1; i < allPos.Length - 1; i++){
            allPos[i] = Vector3.Lerp(beginPos, endPos, i/(gears - 1f));
        }
        //默认结果点为起点
        Vector3 resultPos = beginPos;
        //遍历所有点
        for(int i=0; i < allPos.Length - 1; i++){
            if(CanSeeTarget(allPos[i])){
                resultPos = allPos[i];
                break;
            }
        }
        //摄像机移动
        transform.position = Vector3.Lerp(transform.position, resultPos + dir, moveSpeed * Time.deltaTime);
        //获取方向向量
        Vector3 lookDir = target.position - resultPos;
        //摄像机旋转           
    transform.rotation=Quaternion.Lerp(transform.rotation,Quaternion.LookRotation(lookDir), turnSpeed * Time.deltaTime); //将欧拉角Y置零 transform.eulerAngles = new Vector3(transform.eulerAngles.x, 0, transform.eulerAngles.z); } //能否看到玩家 void CanSeeTarget(Vector3 pos){ //发射射线(起点,方向向量,射到的物体) if(Physics.Raycast( pos, target.position - pos ,out hit)){ //能否看到玩家 if(hit.collider.CompareTag(Tags.Player)){ return true; } } return false; } }

  

posted on 2017-04-26 17:23  chenquanlong  阅读(590)  评论(0编辑  收藏  举报