原理是相机朝人物发射一条射线,设置相机和人物正上方位置之间5个差值 当射线检测不到人物时,相机变换位置并旋转角度
public class CameraMove : MonoBehaviour {
public float moveSpeed;
private Transform player;
Vector3 direction; //摄像机指向玩家的向量
RaycastHit hit;
float distance; //摄像机与人之间的距离
private Vector3[] viewPoints; //摄像机对着Playerd发射线的观察点
public float turnSpeed; //摄像机达到观察点后旋转的速度
void Start () {
player = GameObject.FindWithTag(Tags.Player).transform;
viewPoints = new Vector3[5];
distance = Vector3.Distance(transform.position, player.position);
direction = player.position - transform.position;
}
private void LateUpdate()
{
Vector3 startPos = player.position - direction; //第一个观察点
viewPoints[0] = startPos;
Vector3 endPos = player.position + Vector3.up * distance; //第五个观察点
viewPoints[4] = endPos;
viewPoints[1] = Vector3.Lerp(startPos, endPos, 0.25f);
viewPoints[2] = Vector3.Lerp(startPos, endPos, 0.5f);
viewPoints[3] = Vector3.Lerp(startPos, endPos, 0.75f);
Vector3 tempViewPoint = viewPoints[0];
for (int i = 0; i < viewPoints.Length; i++)
{
if (CheckView(viewPoints[i])) //如果能看到玩家
{
tempViewPoint = viewPoints[i]; //保存改坐标
break;
}
}
//把相机移动到观察点上
transform.position = Vector3.Lerp(transform.position, tempViewPoint, Time.deltaTime * moveSpeed);
//沿着X轴进行旋转
SmoothRotate();
}
/// <summary>
/// 检测摄像机在所指定的点pos处能否看得到玩家
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
bool CheckView(Vector3 pos)
{
Vector3 dir = player.position - pos;
//沿着
if (Physics.Raycast(pos,dir,out hit))
{
if (hit.collider.tag==Tags.Player)
{
return true;
}
}
return false;
//Ray ray= Camera.main.ScreenPointToRay(player.position);
}
void SmoothRotate()
{
//1.得到要旋转到的目标方向向量
Vector3 dir = player.position - transform.position;
//2.得到要旋转的角度(四元数)
Quaternion q = Quaternion.LookRotation(dir);
//3,使用差值,让摄像机又快到慢旋转
transform.rotation = Quaternion.Lerp(transform.rotation, q, Time.deltaTime * turnSpeed);
// 只让X轴旋转 把其他两个方向的角度归零
transform.eulerAngles = new Vector3(transform.eulerAngles.x, 0, 0);
}
}