脚本挂载至相机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMovement : MonoBehaviour
{
public float smooth = 1.5f;
private Transform player;//角色
private Vector3 relCameraPos;
private float relCameraPosMsg;
private Vector3 newPos;
private void Awake()
{
player = GameObject.FindGameObjectWithTag(tag.player).transform;
//角色到相机的向量
relCameraPos = transform.position - player.position;
//向量长度
relCameraPosMsg = relCameraPos.magnitude - 0.5f;
}
private void FixedUpdate()
{
//相机的初始位置=角色位置+相机到角色的相对位置
Vector3 standardPos = player.position + relCameraPos;
//相机俯视角位置=角色位置+角色正上方*相对位置的向量长度
Vector3 abovePos = player.position + Vector3.up * relCameraPosMsg;
//存储相机初始位置到正上方位置lerp中的插值[ 0 , 0.25f , 0.5f , 0.75f , 1]
Vector3[] checkPoints = new Vector3[5];
checkPoints[0] = standardPos;
checkPoints[1] = Vector3.Lerp(standardPos, abovePos, 0.25f);//位置在0.25位置的时候
checkPoints[2] = Vector3.Lerp(standardPos, abovePos, 0.5f);
checkPoints[3] = Vector3.Lerp(standardPos, abovePos, 0.75f);
checkPoints[4] = abovePos;
for (int i = 0; i < checkPoints.Length; i++)
{
if (ViewingPosCheck(checkPoints[i]))
{
break;
}
}
transform.position = Vector3.Lerp(transform.position, newPos, smooth * Time.deltaTime) ;
SmoothLookAt();
}
/// <summary>
/// Camera根据checkPoints集合中各分段的位置值投射一条长度relCameraPosMsg的射线,如果可以射到player,那么就不继续遍历checkPoints
/// </summary>
/// <param name="checkPos"></param>
/// <returns></returns>
bool ViewingPosCheck(Vector3 checkPos )
{
RaycastHit Hit;
if (Physics.Raycast(checkPos,player.position-checkPos,out Hit,relCameraPosMsg))
{
if (Hit.transform!=player)
{
return false;
}
}
newPos = checkPos;
return true;
}
/// <summary>
/// 让相机平滑至目标角度
/// </summary>
void SmoothLookAt()
{
Vector3 relPlayerPositon = player.position - transform.position;
Quaternion lookAtRotation = Quaternion.LookRotation(relPlayerPositon,Vector3.up);
transform.rotation = Quaternion.Lerp(transform.rotation,lookAtRotation,smooth*Time.deltaTime);
}
}