Unity3D中的高级摄像机跟随

时间:2021-08-14 16:16:56

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