VR中运动控制器的传送系统
创建一个VRPawn
-
新建一个BluePrint,父类选择Pawn,我们命名为VRPawn,打开它。
-
添加一个Scene命名为CameraRoot
-
在CameraRoot节点下添加一个Camera
-
在DefaultSceneRoot下添加两个MotionContoller分别对应左手和右手,分别命名为“MotionController_L”和“MotionController_R”同时设置Visualization中的DisplayDeviceModel为True,DisplayModelSource为SteamVR。
-
设置右手的MotionSource为Right。
-
将VRPawn拖到场景中,并设置
添加并设置导航网格物体
首先要添加一个导航网格物体,它允许我们在导航网格物体覆盖的区域四处走动,要添加导航网格物体,先找到“模式”面板,选择“体积”,在下方找到“导航网格边界”(Nav Mesh Bounds Volume),然后将其拖到场景中。
如果看不到绿色的网格那说明你没开启显示
在其细节设置中找到“笔刷设置”(Brush Setting),改变其XYZ的值直到覆盖场景区域
使用导航网格边界时,所有对象都必须有碰撞组件,这样导航网格才知道哪些区域可以走动。
选中一个物体的静态网格
在这里面设置碰撞
如果还有一些区域是不希望用户可以到达的,可以添加“导航网格物体修改器体积”(Nav Mesh Modifier Volume)
会发现它所在的区域会破坏导航网格物体。所以我们可以调整其大小与位置到一些不希望用户过去的地方。
修改VRPawn
新建两个变量
变量名 | 类型 | 描述 |
---|---|---|
bTeleport | Bool | 是否可传送 |
teleportLoc | Vector | 要传送的目标坐标 |
新建一个函数
这个函数主要的功能就是传送
函数名 getTPDestination
它需要两个参数
参数名 | 类型 | 描述 |
---|---|---|
Position | Vector | 传送的位置坐标 |
ForwardVector | Vector | 朝向 |
连线
右击添加节点,输入并选择“LineTraceByChannel”。
这个节点会从我们所在位置向传送目的地发射出一条射线,用这种方法我们就能在按下某个键时计算出“teleportLocation”的位置。
将Postion与Start连接起来。
要得到End需要通过ForwareVector计算:
将Forware*10000后与Position相加。乘的系数即为射线的长度。
接下来要计算射线击中的对象
拖动“Out Hit” 并选择“Break Hit Result”来展开结构体。
只要我们击中对象就会得到这些信息,但我们只需要用到其中的一小部分信息。
首先要确定“Up的值”,所以我们要用到其中的“Normal”,然后对它使用点积,拖动后,搜索“dot product”:
将Z设置为1
接下来把结果和一个浮点数比较一下,判断点积结果是否比浮点数大。
将float设置为0.9
把判断结果赋值给"bTeleport"
接下来判断是否可以传送
从这里开始我们要使用导航网格物体,回到“Break Hit Result”,拖动“Location”,然后搜索“Project”,选择“ProjectPointToNavigation”
添加“teleportLoc”变量,并选择set,如果可以传送,则把ProjectedLocation赋给teleportLoc。
最后我们在场景中绘制一个调试圆柱体,方便显示传送点在哪里。在set后面继续添加引脚,输入“Draw Debug Cylinder”,将半径设置为50,设置颜色,把宽度改为2。
设置圆柱的高度,回到Break Hit Result”,拖动“Normal”输出引脚,搜索“ *”,它的值决定了圆柱体的高度,我将其设置为10。
接下来将这个Vector与“teleportLoc”相加,并连接Start和End。
记住“Draw Debug Cylinder”只能在开发中使用,打包项目时我们需要用一个更正式的对象来代替它,如一个静态网格体。
事件图表调用
最后我们需要在事件图表中调用函数。
找到Event Tick。
这个事件在场景中的每帧都会触发