学习Unity过程中,遇到了角色被墙体遮挡这一问题。能想到的解决方法有“对墙体不进行渲染”和“拉近视角”这两种,前者好像在网游里见得比较多,而其他端游和主机游戏还是用的后者。
这里试着用拉近视角的方式,令角色物体头部每帧朝相机位置发出射线,若射线打到了墙体,则将相机移动到打击点处。
代码如下:
public float distance;
public Transform character;
void Start()
{
character = GameObject.Find("Player").transform; //传入角色物体的引用
distance = Vector3.Distance(transform.position, character.position); //记录相机和角色的初始距离
}
void MoveCamera()
{
if (Physics.Raycast(character.position, //从角色物体的原点发出射线(一般情况下原点是角色模型的脚部,所以需要自己根据实际调整该点)
transform.position - character.position, //射线方向
out RaycastHit hit,
distance) //最大距离只需要到相机为止
&& hit.collider.CompareTag("Wall")) //如果射线打到了collider,则判断其是否是墙体
{
Vector3 newPoint = hit.point; //若是墙体,则将打到的点设为相机的新位置
transform.position = newPoint;
}
else
{
//如果射线没有打到任何collider,或者打到的不是墙体,则将相机和角色之间的距离还原
Vector3 p = (transform.position - character.position).normalized * distance;
transform.position = character.position + p;
}
}
让我来运行看看——
这正是我想要的效果。再优化一下,使用Vector3.Lerp()方法使相机移动更为平滑,修改代码如下:
float distance;
Transform character;
void Start()
{
character = GameObject.Find("Player").transform; //传入角色物体的引用
distance = Vector3.Distance(transform.position, character.position); //记录相机和角色的初始距离
}
void MoveCamera()
{
if (Physics.Raycast(character.position, //从角色物体的原点发出射线(一般情况下原点是角色模型的脚部,所以需要自己根据实际调整该点)
transform.position - character.position, //射线方向
out RaycastHit hit,
distance) //最大距离只需要到相机为止
&& hit.collider.CompareTag("Wall")) //如果射线打到了collider,则判断其是否是墙体
{
Vector3 newPoint = hit.point; //若是墙体,则将打到的点设为相机的新位置
transform.position = Vector3.Lerp(transform.position, newPoint, 0.5f); //速度比例这里设为0.5,如果感觉移动慢了可以调高数值
}
else
{
//如果射线没有打到任何collider,或者打到的不是墙体,则将相机和角色之间的距离还原
Vector3 p = (transform.position - character.position).normalized * distance;
Vector3 newPoint = character.position + p;
transform.position = Vector3.Lerp(transform.position, newPoint, 0.5f);
}
}
问题这样就解决了。