unity 摄像机对准物体 在吃鸡元年,你们是否也中了,的毒?

unity 摄像机对准物体 在吃鸡元年,你们是否也中了,的毒?

吃鸡的第一年,你也吃鸡中毒了吗?

短短半年时间,吃鸡这个词像病毒一样侵入了每个人的生活,我也不例外。

最近接到项目需求,想在项目中引入吃鸡的一些功能元素。

所以我把实现过程写成文章分享。 本文主要分享

放大镜在鸡身上的实现效果。

这里我使用Unity引擎来实现。 只要了解了它的原理,实现效果就非常简单了。

这里我用两张图为大家分析一下他的实现原理。

unity怎么找到子物体_unity 找到所有子物体_unity 摄像机对准物体

1代表我们相机中的物体,2代表我们最终图像的帧,3代表我们相机的渲染区域,可以看成是无数个平面组成如图4所示,这就形成了一个平面,和最后这些平面根据我们的分辨率组合起来投影到图像帧中。

第二张图是我们修改相机渲染角度后的图片。 可以发现我们的渲染区域缩小了,然后我们的物体在我们4号平面的比例变大了。 然后我们把两个摄像头渲染的游戏视图展示出来

unity怎么找到子物体_unity 摄像机对准物体_unity 找到所有子物体

可以发现我们物体的成像尺寸在减小相机的渲染角度后发生了变化。

这就是我们双镜像的实现原理。

接下来,我们将这个原理应用到我们的实验场景中,看看效果。

第一步

首先创建两个UI,一个是我们的基本镜,一个是我们的放大镜

unity怎么找到子物体_unity 找到所有子物体_unity 摄像机对准物体

注意:镜子一定要放在我们屏幕的正中央,不能有误差,这里我让镜子偏移五个像素,看看效果:

unity 找到所有子物体_unity怎么找到子物体_unity 摄像机对准物体

本来,我们的点正对着目标的第十环。 放大后,它移动了很多。 因为当我们放大镜头的时候,我们的误差也被放大了,所以我们必须让我们的镜头指向屏幕。 中间。

第二步

通过开关镜的操作修改摄像机的照射角度

unity 摄像机对准物体_unity怎么找到子物体_unity 找到所有子物体

注意:这里相机的渲染模式必须是Perspective广角渲染。

上面的原理我们已经分析过了,就是修改相机的渲染角度。 这里我们并不是说修改camera Transform中的angle,而是修改Camera下的Field of View属性的值。

如果上面的原理分析看不懂,我们这里举个栗子。

unity怎么找到子物体_unity 找到所有子物体_unity 摄像机对准物体

这就好比打开手机的拍照功能,然后把镜头拉近。 我们会发现,我们镜头中的照射区域变小了,但是区域内的物体变大了。 这就是这里修改照射角度的原理。

以下代码修改其值:

  public void OpenMirror(ScopeType _scope)
    {
        Float _timesScope = GetTimesScope(_scope);//获取倍镜缩放倍数
        Scope.gameObject.SetActive(true);//倍镜开启
        baseScope.gameObject.SetActive(false);//基础镜关闭
        mainCamera.fieldOfView /= _timesScope;//摄像机渲染角度修改
        mCurrScopeType = _scope;//将镜子的类型储存起来.
    }

第三步

检入更新,在按下右键时判断当前镜像类型,然后决定调用镜像开/关方法。

void Update()
{
   if(Input.GetMouseButtonDown(1))
   {
     if(mCurrScopeType == ScopeType.BaseScope)
     {
         OpenMirror(mCurrChoseScope);
         //mCurrChoseScope存储了所选择的倍镜(尚未开启),mCurrScopeType是当前使用的倍镜
         //在这里注意区分好
     }
     else
     {
         CloseMirror();//关闭倍镜.  
     }
   }
}

最终效果如下:

unity 摄像机对准物体_unity 找到所有子物体_unity怎么找到子物体

这也是目前吃鸡和几款吃鸡手游放大镜的实现方式。

从我个人的角度来看,这种实现方式其实是不合理的,因为它放大的是我们整个游戏视图,而不是镜像区域的局部放大。 比如:彩虹六号里面的放大镜效果比较舒服,他就是把镜面区域的物体局部放大。

那我们来实现一下彩虹六号中的放大效果

彩虹六号的放大原理其实和吃鸡的放大原理是一样的,不同的是它们的放大区域不同,所以实现的思路是两个摄像头加一个3DObject相互配合其他实现它。 将渲染区域绘制成一个RenderTexture,然后将这个RenderTexture赋值给3DObject的shader,

之后我们的副摄像头就忽略了3DObject的渲染,只交给主摄像头去渲染。

也用几张图来分析

unity怎么找到子物体_unity 找到所有子物体_unity 摄像机对准物体

1是主摄像头,2是副摄像头。 它们的位置相同,旋转角度相同unity 摄像机对准物体,只是渲染角度不同。 然后3是我们成像和投影的区域。

副相机缩小渲染角度游戏策划,放大图像,然后将图像渲染成平面图,将这个平面图赋值给图3中的材质球,然后使用主相机渲染图3中的物体.

注意:副机要忽略渲染元素3,忽略的方法是为Cylinder创建一个Layer图层,然后在副机的CuliingMask中忽略那个图层。

unity怎么找到子物体_unity 摄像机对准物体_unity 找到所有子物体

unity怎么找到子物体_unity 摄像机对准物体_unity 找到所有子物体

第一步

首先在主摄像头下创建一个摄像头

我们的缩放逻辑需要更改才能在此相机下操作。

接下来unity 摄像机对准物体,在相机下创建一个圆柱体,这是我们的放大镜。

然后为其Transform属性赋值游戏图片,其中Postion中Z轴的值决定了我们成像区域的大小(这个是根据我们自己的需要设置的,符合要求)。 摄像头的底部是为了让这个图像一直在我们设置的屏幕位置。

unity 摄像机对准物体_unity怎么找到子物体_unity 找到所有子物体

Cylinder设置好之后是这样的

unity 摄像机对准物体_unity怎么找到子物体_unity 找到所有子物体

设置后。 创建 RenderTexture 图像

unity 摄像机对准物体_unity怎么找到子物体_unity 找到所有子物体

然后把我们创建的RenderTexture图片放到我们副摄像头下的TargetTexture属性中,这样摄像头就会把它的视角看到的东西渲染成图片,赋值给我们的RenderTexture。

unity 找到所有子物体_unity怎么找到子物体_unity 摄像机对准物体

再创建一个shader,选择一个可以放置贴图的Shader,把我们的Texture放在上面。

unity 找到所有子物体_unity 摄像机对准物体_unity怎么找到子物体

放置之后,将shader赋给我们的Cylinder,这样我们渲染的场景就会显示在外面的Cylinder上。 效果如下:

unity怎么找到子物体_unity 摄像机对准物体_unity 找到所有子物体

最后显示我们的UI框,然后修改副摄像头的Field of View,开镜时开启副摄像头,关镜时关闭摄像头。 代码修改如下。

public void OpenMirror(ScopeType _scope)

{

float _timesScope = GetTimesScope(_scope);//获取放大镜的缩放倍数

Scope.gameObject.SetActive(true);//开启放大

baseScope.gameObject.SetActive(false);//基础镜像关闭

scopeCamera.fieldOfView /= _timesScope;//相机渲染角度修改

ScopeCamera.fieldOfView.gameObject.SetActive(true);//副摄像头开启。

mCurrScopeType = _scope;//存储镜像的类型。

}

执行后效果如下:

unity怎么找到子物体_unity 找到所有子物体_unity 摄像机对准物体