超阈限空间VR复现
超阈限空间VR复现
鲸拓工作室视频教程已同步发布至B站:https://www.bilibili.com/video/BV1Lg4y1F7Xd
UE版本:5.1.1
创建一个虚拟现实游戏项目
描边选中
主要用到了后期处理体积的后期处理材质
这里的PP_Highlight材质文件,直接从上面提供的工程文件里面迁移过来,后面会专门出视频讲解原理
逻辑实现
打开默认的Pawn文件
在右手食指处创建一个场景组件,用于指示手指的方位
再事件图表里新增一个Tick函数
当我们按下Grasp键的时候,就对当前命中的物体进行对应操作
没按下的时候,就检测当前方位是否有命中物体,如果命中了,就让命中的物体显示出白色描边
选中和描边
LineTrace的核心逻辑如下
SetGlowingEdge的核心逻辑如下
检测击中的物体是否为StaticMeshActor(这里可以改成你想要的任何类型)
- 看这个物体是否可以被抓取
- 如果可以抓取,就把这个物体设为TmpHitTarget,并判断它是否有效
- 然后再看上一帧命中的物体,命名为TmpLastTarget,看它是否有效,这里会有如下四种情况
- TmpHitTarget有效,TmpLastTarget有效,且这二者相等,说明这两帧都指向同一个物体,逻辑不变
- TmpHitTarget有效,TmpLastTarget有效,且这二者不相等,说明这两帧都指向的物体不同,那就取消上一帧那个物体的描边,且将TmpLastTarget设为TmpHitTarget,并让新的TmpLastTarget开启描边
- TmpHitTarget有效,TmpLastTarget无效,说明上一帧没有命中物体,从这一帧开始命中,那就将TmpLastTarget设为TmpHitTarget,并让新的TmpLastTarget开启描边
- TmpHitTarget无效,TmpLastTarget有效,就说明从现在开始不指向新物体了,那就将TmpLastTarget取消描边,且设为空
- 如果发现这个物体不能被抓取的话,就不走上面的逻辑,直接将TmpHitTarget和TmpLastTarget都设为不可描边,同时无效
设置描边的SetCustomDepth函数逻辑如下
这里指示简单的渲染了一下自定义深度,具体的描边逻辑会在上面的材质和后期处理体积里面的执行
最后还需要再Grasp事件里面补充一些逻辑
恒定缩放
如果按下了Grasp键,就需要锁定命中物体,并根据摄像头的位置和旋转,实时计算目标的缩放,让它在视野内位置恒定的大小
详细逻辑在Tick里面的SetTargetScaleByCamera里实现
在物体运动的过程中,摄像机的位置不会发生改变,我们需要根据第一帧中,摄像机与目标物体之间的位置 \(D0\) 和此时目标物体的缩放 \(L\)。实时计算出后续运动过程中,目标物体的缩放 \(Ln\)
这里的常量是 \(D0\) 和 \(L\),我们只需要维护 \(\frac{L}{D0}\) 不变就可以了,这里有如下公式 \[ \frac{L}{D0}=\frac{Ln}{Dn} \\ Ln=\frac{Dn}{D0}L \] 所以实时缩放就这样算出来了,接下来用蓝图来实现出来(会有一些不同,需要多理解一下)
恒定位置
这部分逻辑与缩放有一定类似,如果按下了Grasp键,就需要锁定命中物体。
在第一帧计算出以下三个变量
- 从摄像头处出发,沿摄像头向前向量命中的坐标(忽略目标物体),保存摄像头到这个坐标的距离 \(D2\)
- 摄像头与目标物体之间的距离 \(Dn\)
- \(Dn\) 与 \(D2\) 之间的比值 \(Q\)
然后在接下来的运动中,只需要保证每一帧的 \(Q\) 不变就好(当然,位置策略也可以自己调整)
详细实现逻辑如下