吃鸡的第一年,你也吃鸡中毒了吗?
短短半年时间,吃鸡这个词像病毒一样侵入了每个人的生活,我也不例外。
最近接到项目需求,想在项目中引入吃鸡的一些功能元素。
所以我把实现过程写成文章分享。 本文主要分享
放大镜在鸡身上的实现效果。
这里我使用Unity引擎来实现。 只要了解了它的原理,实现效果就非常简单了。
这里我用两张图为大家分析一下他的实现原理。
1代表我们相机中的物体,2代表我们最终图像的帧,3代表我们相机的渲染区域,可以看成是无数个平面组成如图4所示,这就形成了一个平面,和最后这些平面根据我们的分辨率组合起来投影到图像帧中。
第二张图是我们修改相机渲染角度后的图片。 可以发现我们的渲染区域缩小了,然后我们的物体在我们4号平面的比例变大了。 然后我们把两个摄像头渲染的游戏视图展示出来
可以发现我们物体的成像尺寸在减小相机的渲染角度后发生了变化。
这就是我们双镜像的实现原理。
接下来,我们将这个原理应用到我们的实验场景中,看看效果。
第一步
首先创建两个UI,一个是我们的基本镜,一个是我们的放大镜
注意:镜子一定要放在我们屏幕的正中央,不能有误差,这里我让镜子偏移五个像素,看看效果:
本来,我们的点正对着目标的第十环。 放大后,它移动了很多。 因为当我们放大镜头的时候,我们的误差也被放大了,所以我们必须让我们的镜头指向屏幕。 中间。
第二步
通过开关镜的操作修改摄像机的照射角度
注意:这里相机的渲染模式必须是Perspective广角渲染。
上面的原理我们已经分析过了,就是修改相机的渲染角度。 这里我们并不是说修改camera Transform中的angle,而是修改Camera下的Field of View属性的值。
如果上面的原理分析看不懂,我们这里举个栗子。
这就好比打开手机的拍照功能,然后把镜头拉近。 我们会发现,我们镜头中的照射区域变小了,但是区域内的物体变大了。 这就是这里修改照射角度的原理。
以下代码修改其值:
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();//关闭倍镜.
}
}
}
最终效果如下:
这也是目前吃鸡和几款吃鸡手游放大镜的实现方式。
从我个人的角度来看,这种实现方式其实是不合理的,因为它放大的是我们整个游戏视图,而不是镜像区域的局部放大。 比如:彩虹六号里面的放大镜效果比较舒服,他就是把镜面区域的物体局部放大。
那我们来实现一下彩虹六号中的放大效果
彩虹六号的放大原理其实和吃鸡的放大原理是一样的,不同的是它们的放大区域不同,所以实现的思路是两个摄像头加一个3DObject相互配合其他实现它。 将渲染区域绘制成一个RenderTexture,然后将这个RenderTexture赋值给3DObject的shader,
之后我们的副摄像头就忽略了3DObject的渲染,只交给主摄像头去渲染。
也用几张图来分析
1是主摄像头,2是副摄像头。 它们的位置相同,旋转角度相同unity 摄像机对准物体,只是渲染角度不同。 然后3是我们成像和投影的区域。
副相机缩小渲染角度游戏策划,放大图像,然后将图像渲染成平面图,将这个平面图赋值给图3中的材质球,然后使用主相机渲染图3中的物体.
注意:副机要忽略渲染元素3,忽略的方法是为Cylinder创建一个Layer图层,然后在副机的CuliingMask中忽略那个图层。
第一步
首先在主摄像头下创建一个摄像头
我们的缩放逻辑需要更改才能在此相机下操作。
接下来unity 摄像机对准物体,在相机下创建一个圆柱体,这是我们的放大镜。
然后为其Transform属性赋值游戏图片,其中Postion中Z轴的值决定了我们成像区域的大小(这个是根据我们自己的需要设置的,符合要求)。 摄像头的底部是为了让这个图像一直在我们设置的屏幕位置。
Cylinder设置好之后是这样的
设置后。 创建 RenderTexture 图像
然后把我们创建的RenderTexture图片放到我们副摄像头下的TargetTexture属性中,这样摄像头就会把它的视角看到的东西渲染成图片,赋值给我们的RenderTexture。
再创建一个shader,选择一个可以放置贴图的Shader,把我们的Texture放在上面。
放置之后,将shader赋给我们的Cylinder,这样我们渲染的场景就会显示在外面的Cylinder上。 效果如下:
最后显示我们的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;//存储镜像的类型。
}
执行后效果如下: