Unity3D学习日记(五)实现围绕物品旋转的的摄像机控制

这个是我在公司项目里面发现的一个写的很不错的一个简单的围绕物品选择的一个摄像机控制方法,这个方法比我之前写方法好用而且修复我之前遇到的一个Bug问题,这里我就对这两个方法进行比较说明一下,防止下次再出现这个问题。

我们先来看看第一种围绕物品360度旋转的的方式会出现什么问题呢?这个方式利用了Unity3D的Transform类中LookAt的函数实现的效果,水平方向上实现的效果还是很理想的,但是在垂直方向的效果就 会出现画面颠倒的问题,这样说可能很抽象,这里我们用两种图片进行比较一下就知道大概的问题了,如图所示:


这里我们可以清楚看到已现在摄像机的位置和角度来说阴影位置都是正确的效果,那么我们稍稍往上动一下就会发现问题所在了,如下图所示:


这里你会发现阴影位置突然就变到下面去了,而且非常突然的就跳到下面去了,一开始觉得没啥,但是尝试几次后觉得想吐(PS:画面如果变化的太快眼球适应不下来就会有眩晕呕吐的感觉),因此这个问题需要解决,但是我们先来看看这个效果是怎么实现的再来解决这个bug,我们先来看看代码,代码如下:

 void CameraRotate()
    {
        if(Input.GetMouseButton(0))
        {
           
            x += Input.GetAxis("Mouse X") * RspeedX;
            y -= Input.GetAxis("Mouse Y") * RspeedX;

            y = ClampAngle(y, minAngle, maxAngle);

            Quaternion rotateAngle = Quaternion.Euler(y, x, 0);

            direction = new Vector3(0, camHeight, -distance);
            transform.position = target.position + rotateAngle * direction;
            transform.LookAt(target);

            y = ClampAngle(y, minAngle, maxAngle);

        }
    }
这里我们可以很清楚看到位置摄像机的位置是通过rotateAngle和tartget.position(这是Cube的Transform)进行控制的,这里如果把LookAt注释掉你会发现摄像机就只是做一个单纯平移而已,那么也就是说LookAt函数是控制着摄像机围绕物体旋转的功能,其实如果去研究过Unity3D的API就知道这是一个模拟人注视物品的函数,LookAt是一个带参数函数传入的是注视物品的Transform,也就是说我们只要传入一个位置给它。那么出现bug位置也就是这里了,Unity3D不开源我们就没办修改这个问题了,但是并不表示没办法做出这个效果。现在我们理一下需要什么大体的功能,首先要摄像机角度控制,其次摄像机位置控制,来达到注视物品的效果,了解这个需求就作手开始研究代码了。

刚刚的注释掉LookAt后我们就会发现摄像机的并没有注视着物体,也就是我们缺少一个让摄像机角度的旋转方式,添加后就会发现摄像机会转向物品的位置,最后的代码效果如下:

 void CameraRotate()
    {
        if(Input.GetMouseButton(0))
        {
           
            x += Input.GetAxis("Mouse X") * RspeedX;
            y -= Input.GetAxis("Mouse Y") * RspeedX;

            y = ClampAngle(y, minAngle, maxAngle);

            Quaternion rotateAngle = Quaternion.Euler(y, x, 0);//摄像机偏转角度

            direction = new Vector3(0, camHeight, -distance);//摄像机距离物品的距离
            transform.rotation = rotateAngle;//让摄像机始终转向物品
            transform.position = target.position + rotateAngle * direction;//计算旋转多少角度摄像机需要偏移多少
            //transform.LookAt(target);

            y = ClampAngle(y, minAngle, maxAngle);

        }
    }
下面这个函数为了限制摄像机跑到物品的下方而做的限制。

static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }




你可能感兴趣的:(Unity3D学习日记)