最简单的一种就是先设置好摄像机跟物体的相对距离,
在脚本里就可以由物体的位置,跟相对距离,就可以求出摄像机的位置,用差值的方法可以让摄像机平滑跟随。
public class CamFollow1 : MonoBehaviour
{
private Vector3 offset;
public Transform player;
void Start()
{
offset = player.position - transform.position;
}
void Update()
{
transform.position = Vector3.Lerp(transform.position, player.position - offset,Time.deltaTime*5);
}
}
实现一种注视的效果,可以对rotation做下处理
void Update()
{
transform.position = Vector3.Lerp(transform.position, player.position - offset,Time.deltaTime*5);
Quaternion rotation = Quaternion.LookRotation(player.position-
transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation,
rotation,Time.deltaTime*3f);
}
这样子,人物在走动的时候,摄像机就是一边注视着人物,一边跟着移动
但是,当有墙体,或其他高大的物体遮挡住人物,
摄像机就无法看到人物,玩家自然也看不到,
在上面的基础上做更近一步的扩展
在人物头顶往下看,肯定可以看得到人物,
所以我们要做的就是把摄像机的位置向人物头顶去调整,直到可以看到人物。
using UnityEngine;
using System.Collections;
public class CamFollow3 : MonoBehaviour
{
private Transform player;//英雄位置
private Vector3 offset; //摄像机和英雄相对位置
private float distance;//距离
private Vector3[] points = new Vector3[5];//5个点作为摄像机位置的选择
private Vector3 targetPos;//筛选后的摄像机位置
void Awake()
{
player = GameObject.FindWithTag("Player").transform;
offset = transform.position - player.position;
distance = offset.magnitude;
}
void FixedUpdate()
{
//更新5个点的位置
points[0] = player.position + offset;
points[4] = player.position + Vector3.up*distance;
points[1] = Vector3.Lerp(points[0], points[4], 0.25f);
points[2] = Vector3.Lerp(points[0], points[4], 0.5f);
points[3] = Vector3.Lerp(points[0], points[4], 0.75f);
points[4] = Vector3.Lerp(points[0], points[4], 0.9f);
targetPos = FindCameraTarget();
AdjustCamera();
}
private Vector3 FindCameraTarget()
{
Vector3 result = points[points.Length - 1];//头顶位置
//从低到高遍历
for (int i = 0; i < points.Length; ++i)
{
if (IsHitPlayer(points[i], player.position))
{
result = points[i];
break;
}
}
return result;
}
private Ray ray;
private RaycastHit hit;
/// <summary>
/// 从origin发射一条射线检测是否碰到player,
/// 碰到则表示摄像机在此位置可以看到player
/// </summary>
/// <param name="origin"></param>
/// <param name="target"></param>
/// <returns></returns>
bool IsHitPlayer(Vector3 origin, Vector3 target)
{
bool result = false;
Vector3 dir = target - origin;
ray = new Ray(origin,dir);
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.tag == "Player")
{
result = true;
}
}
return result;
}
/// <summary>
/// 调整摄像机位置
/// </summary>
void AdjustCamera()
{
transform.position = Vector3.Slerp(transform.position, targetPos, Time.deltaTime * 6);
Quaternion rotation = Quaternion.LookRotation(player.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 33f);
}
}