1:实现摄像机跟随
实现思想:计算出摄像机和游戏物体的相对坐标,在Update中让摄像机的坐标等于相对坐标加上物体的坐标,这样摄像机会随着物体的移动而移动。
start
offect=camera.transform.position-player.transform.position
update
camera.transform.position=offect+player.transform.position
private Vector3 offect; private Transform PlayerPosition; void Awake() { PlayerPosition = GameObject.Find(Managetags.player).GetComponent<Transform>(); } void Start () { offect = gameObject.transform.position- PlayerPosition.position; } void Update () { FollowPlayerMe(); gameobject.transform.position=offect+PlayerPosition.position; }
这样摄像机放的太高会被一些物体挡住,拍摄不到物体,所以这个方法不太实用
2:摄像机在跟随时会被一些物体挡住,解决这个问题(摄像机离物体太远时,中间可能会有障碍物)
摄像机的第一个位置就是用上面的方法计算出的位置,最后一个位置是在物体的正上方,摄像机的高度是不会变化的(只是对这种处理方法而言)
在这个向量之间多取几个位置,用射线来检测二者之间是否有障碍物,选一个没有障碍物的位置放摄像机。
在向量中取五个点,依此检验五个点中谁能符合要求,就把摄像机放在那个点上。
offect=camera.transform.position-player.transform.position
第一个位置:
BeginPos1=player.transform.position+offect
第五个位置:
Endpos5=New Vector3(player.transform.position.x,player.transform.position.y+BeginPos1.y,player.transform.position.z)
不过有的人的第五个位置用向量的长度求出的,只是高度更高一点。
Endpos5=BeginPos1.Mangitude*vector3.Up+player.transform.position
Vector3.Mangitude是得到向量的长度。
第二个位置
Pos2=vector3.lerp(BeginPos1,EndPos5,0.25f)
第三个位置
pos3=vector3.lerp(Beginpos1,EndPos5,0.5f)
第四个位置
pos4=vector3.lerp(beginPos1,Endpos5,0.75)
把五个位置存放在数组中
Vector3[] PosArray=new Vector3[]{BeginPos1,Pos2,Pos3,Pos4,EndPos5}
初始化摄像机的位置
vector3 target=BeginPos1
检测五个位置那个更合适
for(int i=0;i<=4;i++)
{
RayCastHit rayhit//存储射线的碰撞信息
if(Physics.RayCast(posArray[i],playerposition.transform.position-BeginPos1,out rayhit))//bool Physics.RayCast(射线发射点,射线发射方向,射线的碰撞信息,(射线的长度))
{//射线碰撞到物体时
if(rayhit.collider.tag=="player")//射线碰到玩家时,就是最佳的位置
{
target=PosArray[i];
break;
}
//碰到其他物体,表明该位置不行,换下一个位置检测
else{
continue;
}
}
else{//射线未碰撞到物体,因为我们更改摄像机的位置时并为改摄像机的朝向
target=PosArray[i]//射线未碰撞到物体,我们暂时把他设为理想的位置
}
}
gameobject.transform.position=target;
void FollowPlayerMe() { //计算出摄像机的五个位置 BeginPos1 = offect + PlayerPosition.position;//第一个位置 EndPos1 = new Vector3(PlayerPosition.transform.position.x, PlayerPosition.transform.position.y + BeginPos1.y, PlayerPosition.transform.position.z); // EndPos1 = offect.magnitude * Vector3.up + PlayerPosition.position;//得到摄像机的第五个位置 Vector3 target = BeginPos1;//默认第一个位置为摄像机的位置 VecPos1 = Vector3.Lerp(BeginPos1, EndPos1, 0.25f);//摄像机的第二个位置 VecPos2 = Vector3.Lerp(BeginPos1, EndPos1, 0.5f);//摄像机的第三个位置 Vecpos3 = Vector3.Lerp(BeginPos1, EndPos1, 0.75f);//摄像机的第四个位置 Vector3[] PosArray = new Vector3[] { BeginPos1,VecPos1,VecPos2,Vecpos3,EndPos1};//将所有的位置放在数组中,逐个检测 for (int i = 0; i <= 4; i++) { RaycastHit rayHit;//存储射线的碰撞信息 if (Physics.Raycast(PosArray[i], PlayerPosition.transform.position - PosArray[i], out rayHit))//射线碰撞到物体 { if(rayHit.collider.tag!=Managetags.player)//碰撞到的是其他物体,就检测在一个位置 { continue; } else { target = PosArray[i];//碰撞到的是玩家,把该位置设为摄像机的位置,并终止检测 break; } } else//射线未碰撞到物体时,把该位置暂时设为摄像机的位置 { target = PosArray[i]; } } this.transform.position = Vector3.Lerp(gameObject.transform.position, target, Time.deltaTime*FollowSpeed);
}
3:实现摄像机跟随时,摄像机移动太急,导致镜头太抖
最终调整位置时用插值运算(插值运算一般要放在不断更新的函数中)
gameobject.transform.position=vector3.lerp(gameobject.transform.position,target,Time.deltatime*speed)
gameobject.transform.LookAt(player.transform.position)
Quaternion nowRotation = transform.rotation; this.transform.position = Vector3.Lerp(gameObject.transform.position, target, Time.deltaTime*FollowSpeed); transform.LookAt(PlayerPosition.position); Quaternion.Lerp(nowRotation, transform.rotation, Time.deltaTime * FollowSpeed);