看siki学院的秘密行动教程的时候,对人物的视角控制有了新的学习体会,不再是单一的第三人称视角对人物进行跟踪,而是加上了部分相机是否被其他物体遮挡的判断
正常情况下,我们对相机的控制是如下的:
- 我们会发现其实这个相机追踪已经可以跟随人物,但是它有一个明显的缺点,那就是当人物站到了某些过高的遮挡物前,由于摄像机固定的角度无法拍摄到人物当前全景,这是一个需要优化的地方
下文就对如何进行改进进行描述
我们先看下初始代码:
public Transform player;
private Vector3 distance;
private void Awake()
{
distance = transform.position - player.transform.position;
}
public void Update()
{
transform.position = distance + player.transform.position;
}
改进方法就是我们再定义几个相机视野位置然后通过射线检测来进行判断能否看到人物进行相应的调整
代码最终如下:
public void Update()
{
// transform.position = distance + player.transform.position;
Vector3 beginPos = distance + player.transform.position;
Vector3 endPos = distance.magnitude * Vector3.up + player.transform.position;
Vector3 pos1 = Vector3.Lerp(beginPos, endPos, 0.25f);
Vector3 pos2 = Vector3.Lerp(beginPos, endPos, 0.5f);
Vector3 pos3 = Vector3.Lerp(beginPos, endPos, 0.75f);
Vector3[] posArray = new Vector3[] { beginPos, pos1, pos2, pos3, endPos };
Vector3 targetPos = posArray[0];
for(int i = 0; i < 5; i++)
{
RaycastHit hitInfo;
if (Physics.Raycast(posArray[i], player.transform.position - posArray[i],out hitInfo)){
if (hitInfo.collider.tag != TAGS.player)
{
continue;
}
else
{
targetPos = posArray[i];
break;
}
}
else
{
targetPos = posArray[i];
break;
}
}
Quaternion nowRotation = transform.rotation;
transform.LookAt(player.transform);
transform.rotation=Quaternion.Lerp(nowRotation, transform.rotation, rotateSpeed * Time.deltaTime);
transform.position = Vector3.Lerp(transform.position, targetPos, moveSpeed * Time.deltaTime);
}
其中 endPos中distance.magnitude * Vector3.up 表示为只要相机的高度Y坐标 通过加上人物的坐标就是获得人物正上方的坐标,将此坐标设定为最差情况(相机竖直朝下拍摄)
然后通过插值运算 对中间3个变量三维坐标赋值,可以理解为由beginPos到endPos两点之间形成的直线按照一定比例赋值
最后再用四元数和向量的插值运算控制相机旋转和位置移动(更加顺滑过渡)
最终效果如下:
可以看到整个人物而且不被障碍物遮挡了!
ps:将近两个月没更新了…这篇其实很早就差不多写完了,硬是拖了半天,懒癌晚期没得救了…我会开始勤奋起来的!