开发环境
操作系统版本:MacOS 10.14.6
脚本开发环境:Visual Studio 2019 for Mac 8.3.3
游戏引擎版本:Unity Hub 2.2.0 Unity 2017.4.34f1 LTS
编写脚本代码
- 新建CameraFollowObject脚本,并绑定到Main Camera摄像机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollowObject : MonoBehaviour {
public float smoothRotation = 1.5f; //平滑旋转系数
public float smoothCamera = 1.5f;
private Transform player; //表示Player对象上的Transform组件
private Vector3 relCameraPos; //表示Player到Camera的相对位置
private float relCameraPosMag; //表示Player对象到Camera的向量长度
private Vector3 newPos; //摄像机新位置
void Awake()
{
player = GameObject.FindWithTag("Player").GetComponent<Transform>();
relCameraPos = transform.position - player.transform.position; //得到两个三维点的向量
relCameraPosMag = relCameraPos.magnitude - 0.5f; //获取两个三维点的距离-0.5f(偏移量)
}
/// <summary>
/// 检测给定的位置是否合适
/// </summary>
/// <param name="checkPos"></param>
bool ViewingPositionCheck(Vector3 checkPos)
{
RaycastHit hit; //射线碰撞信息
//发出一条射线,从checkPos发射,到Player的方向,长度为relCameraMag,输出碰撞信息,给出是否碰撞
if (Physics.Raycast(checkPos,player.position-checkPos,out hit,relCameraPosMag))
//如果碰撞信息不是player
if (hit.transform!=player.transform)
return false;
//如果碰撞到是player,则将检测位置给新位置
newPos = checkPos;
return true;
}
/// <summary>
/// 让摄像机始终正对角色
/// </summary>
void SmoothLookAt()
{
//创建摄像机到Player的向量(相对位置)
Vector3 relPlayerPos = player.position - transform.position;
//创建旋转角度:摄像机从当前位置旋转到Player位置
Quaternion lookAtRotation = Quaternion.LookRotation(relPlayerPos,Vector3.up);
//摄像机旋转,从当前角度均匀插值到目标角度
transform.rotation = Quaternion.Lerp(transform.rotation,lookAtRotation, smoothRotation * Time.deltaTime);
}
void FixedUpdate()
{
//摄像机标准位置=玩家位置+玩家相对于Camera位置
Vector3 standardPos = player.position + relCameraPos;
//俯视位置:表示Player位置+向上方向*relCameraPosMag长度
Vector3 abovePos=player.position+Vector3.up*relCameraPosMag;
//检测5个点
Vector3[] checkPoints = new Vector3[5];
checkPoints[0] = standardPos;
checkPoints[1] = Vector3.Lerp(standardPos,abovePos,0.25f);
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 (ViewingPositionCheck(checkPoints[i]))
{
break;
}
}
transform.position = Vector3.Lerp(transform.position, newPos, smoothCamera * Time.deltaTime);
SmoothLookAt();
}
}