处理unity第一第三人称游戏中的摄像机穿墙的问题

在之前我花过一段时间做了一个比较简单的第三人称射击类游戏
发现一个很难搞的BUG
就是在我们设定的摄像机和主角距离的空隙中间 如果有一些物体 会挡住主角
会给人极差的游戏体验
下面有两种解决方案 但是都存在一些小小的缺陷
两种都是用到射线的知识 其中一种是检测到中间存在物体 改变摄像机和主角之间的距离达到效果
另一种是检测到之后改变3D物体的透明度 来实现效果

1.简单的场景搭建

我为了实现效果 在场景中创建了一个小球 和一个cube当做墙
然后设置摄像跟随小球移动
下面是最简单的代码


 	private void Start()
    {
        Cursor.lockState = CursorLockMode.Locked; //将光标锁定到游戏窗口的中心
        offset = transform.position - Player.transform.position;
   }
    transform.LookAt(Player.transform);
	transform.position = Player.transform.position + offset;

给小球添加一句

 transform.Translate(new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) * Time.deltaTime * 3);

即可 在unity中即可实现简单跟随效果 这是如果把Cube插在中间 会很难受
就像这样
在这里插入图片描述

2.解决方法1(利用改变距离)

我们的思路是检测距离 然后改变位置
实现如果挡住的话 就把摄像机移到挡住我们摄像机的物体之前

 private void ProcessMode()
    {
        transform.LookAt(Player.transform);
        transform.position = Player.transform.position + offset;
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit, 1000))
        {
            if (hit.collider.tag == "Player")
            {
                isBall = true;
            }
            else
            {
                isBall = false;
                float dis = Vector3.Distance(transform.position, hit.point);
                if (dis < Vector3.Distance(transform.position, Player.transform.position))
                {
                    transform.position = hit.point + new Vector3(0, 0, 1);//加一点偏移量
                }

            }
         }
    }

其中Vector3.Distance(位置1,位置2);这是计算两个物体之间的距离的一个方法
但是这个方法有个很难受的缺陷 就是让摄像机容易和墙体发生碰撞 发生抖动

2.解决方法2(利用改变透明度)

首先改变墙体上边材质的Shader的类型(否则无法改变透明度)
改成Legacy Shader/Transparent/Diffuse类型

private Color StartColor;
private void Start()
{
	StartColor = BarraryObjecrt.GetComponent<Renderer>().material.color;//其中的BarraryObjecrt是墙体
}
 private void ProcessMode2()
    {
        transform.LookAt(Player.transform);
        transform.position = Player.transform.position + offset;
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit, 1000))
        {
            if (hit.collider.tag == "Player")
            {
                isBall = true;
            }
            else
            {
                isBall = false;
            }
        }
        if (!isBall)
        {
            hit.collider.gameObject.GetComponent<Renderer>().material.color = new Color(1, 1, 1, 0.75f);
        }
        else if (isBall)
        {
            hit.collider.gameObject.GetComponent<Renderer>().material.color = StartColor;
        }

    }

这就是两种类型

发布了52 篇原创文章 · 获赞 47 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44302602/article/details/103552552
今日推荐