VR大空间资料 03 —— VRGK使用体验和源码分析

自用文档,UE4.27项目 HTC Vive VR和Oculus Quest 2

SteamVR串流运行于HTC Vive VR 和 Oculus Quest 2设备

打包apk运行于Oculus Quest 2设备

VRGK - Virtual Reality Game Kit v3.0 可蹲下 可看自身IK 无局域网

https://www.unrealengine.com/marketplace/zh-CN/product/vrgk-virtual-reality-game-kit

UE 4.27 -> VRGK v3.0

UE 4.25, 4.26 -> VRGK v2.1

API文档在《虚幻商城 VR IK》

VRGK 基于OculusVR , 不需要Nav自动寻路组件

Dust and Smoke Effects 4.25-4.26

WaterVFXNiagara

http://cheapcg.com/

https://github.com/davidbuenov/VRGK-Community-Project-UE5

虚幻引擎5 VR:虚拟现实游戏套件(VRGK)

https://www.youtube.com/watch?v=YKXwHYGaCqg

2024年1月4日

如果说开发 VR 体验时有一件至关重要的话,那就是虚拟手的有效管理。

在这个频道上,我们专门制作了几个视频来探索这个复杂且有时具有挑战性的主题。

结论很明确:尽管这是一个困难的领域,但有商业解决方案可以提供合理的答案。

其中脱颖而出的解决方案之一无疑是 Divor 的"虚拟现实游戏套件",或者更广为人知的名称为 VRGK。

该套件价格实惠,解决了手物理和与环境中物体有效交互等关键问题。

它显着节省了时间和精力,极大地提高了体验的整体质量。

很遗憾,随着虚幻引擎 5 的到来,开发人员决定不再继续该项目。

从他们的角度来看,维护该项目所需的工作量巨大且无利可图。然而,由于社区的努力,Divor 被说服提供社区版本。

这将允许其他人继续他们的工作,幸运的是,这正是发生的事情。

利用三智者季节,还有什么比在我们的项目中使用此套件更好的礼物呢?

此外,我们将着手做出一些小牺牲,以使用 MetaXR 插件将其移植到最新版本的虚幻引擎。

参考资料:

▶ 立体工作室:https://stereoopticstudios.com/

▶ VRGK - 虚拟现实游戏套件 v3.0:https://www.unrealengine.com/marketpl...

▶ 最终公告: https: //redirect.epicgames.com/?redir。 ..

▶ VRGK-社区:https://github.com/VRGK-Community

▶ 社区不和谐: /discord

▶ 旧版文档 PDF: https://divivor.itch.io/legacy-docs(密码:legacydocs) ▶ Mozilla 公共许可证 (MPL):https: //www.mozilla.org/en-US/MPL/2.0 /

VR手柄按键 Vive 和 Oculus

https://www.rstk.cn/news/729695.html?action=onClick

跳跃 右手面板下键位

VRGK 添加Vive按键输入

TPS 和 VRPawn 惯性作用inertia

1,平板移动 setActorLocation 开关Teleport

2,平板移动 addWorldOffset 开关Teleport

1-1平板使用setActorLocation进行位移,Teleport为False,TPS正常跟随移动,VRPawn和物理Cube会有移动的惯性动量,平板速度再快则会甩出去

1-2平板使用setActorLocation进行位移,Teleport为True, TPS正常跟随移动,VRPawn和物理Cube则呆在原地不随板子移动

2-1平板使用setActorLocation进行位移,Teleport为False,碰撞体包裹中的物体,TPS和静态物体会两倍速位移,原因是他们已经在随板子移动,又添加了移动增量,如果物理盒子加了overlap事件,则也会2倍数位移

VRPawn和物理盒子则带着惯性动量跟随板子移动

2-2Teleport为True,物理盒子如果不加overlap,则不移动,加了overlap则随板子位移,TPS和静态物体二倍数,VRpawn不移动

2-3Teleport为False,碰撞体的offset的Teleport为true,同2-1

2-4Teleport为True,碰撞体的offset的Teleport为true,同2-2

直升机位移最好使用event tick,否则vrpawn用的eventTick不能同步

即使设置0.01进行位移,vrpawn丢帧导致位移错误

Review项目

GameInstance

运行游戏后只有一个GameInstance

EventGraph 初始化,读取持久存档和全局设置;关闭时,保存存档;关卡启动时,初始化声音

PersistentSaveGameGraph 存档模块,有则读取,无则新建BP_PersistentSaveGameObject对象

SettingsGraph BPO_Settings对象的初始化,并通过settings对象进行参数调用和事件分发监听绑定

Settings通过方法获取存档配置中的选项

需要调用Setting对象的时候,使用自定义蓝图函数库 BluePrintFunctionLibrary中的Get BPO Game Setting获取Setting对象

BPO_Setting中的方法

蓝图函数库中从GameInstance对象中获取其成员Setting实例对象

蓝图函数库中获取GameInstance实例对象

Settings事件分发的call和bind

获取setting对象后,绑定监听事件分发

UI调用setting对象的方法,其方法中调用了call

绑定监听在具体对象中实现

BPO_Setting中的定义了方法对事件分发进行了Call调用

UI中调用了setting对象的方法

存档对象 BP_PersistentSaveGame

设置对象 BPO_Settings

GameMode

每个关卡都有单独的GameMode

如前后关卡中GameMode下PlayerController 配置相同时,上个关卡中PlayerController 不会进行销毁

Content/VRGK/Blueprints/Core

父类:BP_VRGameModeBase 并实现接口 BPI_VRGameMode

GameMode使用:子类:BP_DemoGameMode

初始化创建对象: BP_MenuController菜单UI、BP_VRSpectator观察着、BP_PlayerVignette黑圈视野、BP_CameraWaterOverlay水下视野

BP_VRSubtitles副标题UI

打开Menu菜单时,专门生成一个VRPawn射线控制UI

通过接口返回对象来调用GameMode中创建的一系列对象

朝向和pawnCamera一致

包裹材质球

Set custom primitive Data Float,Mesh的Render中配置,材质球中也勾选配置

自定义基元数据配置alpha值,这么使用是为了优化减少DrawCall

勾上Use Custom Primitive Data则这个参数就不可在材质里修改默认值,同样材质实例里也找不到该参数

传递参数给Custom Primitive Data,编辑器面板在Rendering下面的Custom Primitive Data可以增删相应的数据,蓝图中,有Set Custom Primitive Data从float到Vector4四个函数

开启移动端Dynamic Instance,需要在项目配置ini中加一行,把r.Mobile.SupportGPUScene设为1

如何使用 Custom Primitive Data

https://zhuanlan.zhihu.com/p/83529624

优化UE4性能 、减少DrawCall,材质中使用自定义基元数据

https://zhuanlan.zhihu.com/p/215545723

Spectator 观察者OB模式

切换观察镜头Type,镜头捕获画面2D组件

Vignette 黑圈视野 虚影效果

通过黑盒子实现

瞬移,Instant为true,小黑盒被隐藏了则显示出来,小黑圈播放从无到有的动画(延长版),0.05s后,执行0.3s的小黑圈淡出,并隐藏小黑盒

移动,Instant为false,小黑盒被隐藏了就显示小黑盒,并播放淡入动画0.3s复现黑圈;

如果持续移动,则一直执行显示小黑盒,小黑盒已经显示的状态就不继续执行;

最后停止移动执行0.3s的小黑圈淡出,并隐藏小黑盒

黑圈材质为自定义基元数据处理淡入淡出的alpha值

临时显示视野黑圈,在VRGamePawn中被调用

左手前后左右移动

右手左右转向

瞬移 【唯一的瞬息true】

每帧调用 根据角色速度值

水下镜头 BP_CameraWaterOverlay

自定义基元数据 设置水材质

绑定监听分发事件OnTrackerStateUpdate

添加自定义组件BPC_TaggedComponentOverlapTracker,用于注册原始组件Overlap的Tracker事件

在自定义组件中,OverlapBegin添加组件到数组,OverlapEnd则从数组中移除触碰的组件

副标题 BP_VRSubtitles

widgetRoot 绝对值scale

scene 绝对坐标

定时器每0.2s执行,判断当前scene值推断的widgetroot值是否大于30位移或15角度偏移,

是则进行0.4s一次的旋转值lerp插值更新,把widgetroot的旋转值渐变到scene推断的位置

eventtick 每帧同步scene组件坐标值为actor坐标值

这个蓝图对象 attach吸附到camera上,但是scene节点为绝对坐标系,需要动态修改。

如果是scene节点是相对坐标系则实时跟随镜头移动,无法实现延迟转向。

定时器0.2s执行,获取当前吸附在Camera节点上的自身actor的坐标值,并计算前方80cm 下方25cm处的WidgetRoot坐标值

吸附在镜头上

FPS高度96的时候

Camera相对高度64,绝对高度160,所以umg对象高度也是160

UI是进入房间,触碰overlapBegin时执行

Pawn

父类:Content/VRGK/Blueprints/Player/PlayCore/BP_VRBasePawn

子类:Content/VRGK/Blueprints/Player/PlayCore/BP_VRGamePawn

GameMode内使用:子类:Content/VRGK/Blueprints/Player/GamePawns/BP_VRPhysicsPawn

BP_VRBasePawn

VRNotifications 判断头显是否戴上,只有Oculus有返回状态值,steamVR就手动修改返回true

Set Tracking Origin 节点

Origin参数

Floor Level:VR设备中,定位的地面高度,为Z平面

Eye Level:VR设备中,定位的那一刻,头盔的高度,为Z平面

设置跟踪原点为地面 set tracking origin

坐立式体验,则可以设置为eye level

换装功能

1.可通过修改材质实现换装。

2.通过修改Mesh实现换装。1个角色由多个Mesh组成,比如:头,脚,身体,手都是单独的Mesh。它们共用一个骨骼,共用同一个动画蓝图。

如何实现这些Mesh共用同一个动画蓝图呢,参照如下图。

SetMasterPoseComponent

所有的SkeletalMesh共用Mesh节点的动画蓝图。共用动画蓝图节约资源

角色材质通道

Mesh材质球通道,0身体、1logo、2手、3头

Spectator 材质球通道2个,1为胸口logo

消防员材质球通道

0-脸 1-眼 2-脚 3-手和胸 4-玻璃面罩 5-口罩呼吸机 6-头盔

工具类

BPFL_GlobalFunctions

动画Anim

标准站立Standing添加了Notify ResetFootPlacement

LeftFootPlaced

左脚放置之后抬起来,

右脚收回

手指动作

动画蓝图 姿势数据

Oculus Android运行

1、只剩双手,身体材质被设置为透明,需要排查

因为源码改为消防员隐藏头部的0通道,变成小白人0通道隐藏身体

2、 OculusLink运行串流 与HTC vive一样执行;

安卓模式:

但是主Map(Map_MuseumV3) 直接Launch Android Quest不行,从其他地图Launch后再进入主Map就可以。

打包同理

  1. 直接打包到手机报错 Failed to open descriptor file .../.../.../VRGK_V3/VRGK_V3.uproject

主Map报错:

复制代码
LogPlayLevel: Error:   08-20 22:38:37.378  5952  5985 D UE4     : [2023.08.20-14.38.37:378][  0]LogStreaming: Error: Couldn't find file for package /Script/SteamVRInputDevice requested by async loading code. NameToLoad: /Script/SteamVRInputDevice
LogPlayLevel: Error:   08-20 22:38:37.378  5952  5985 D UE4     : [2023.08.20-14.38.37:378][  0]LogStreaming: Error: Found 1 dependent packages...
LogPlayLevel: Error:   08-20 22:38:37.378  5952  5985 D UE4     : [2023.08.20-14.38.37:378][  0]LogStreaming: Error:   /Game/VRGK/Blueprints/Player/PlayerCore/BP_VRGamePawn
LogPlayLevel: Error:   08-20 22:38:38.463  5952  5985 D UE4     : [2023.08.20-14.38.38:463][  0]LogProperty: Error: Struct type unknown for property 'StructProperty /Game/VRGK/Blueprints/Player/PlayerCore/BP_VRGamePawn.BP_VRGamePawn_C:SetSteamVRHandCurls:CallFunc_GetFingerCurlsAndSplays_FingerCurls'; perhaps the USTRUCT() was renamed or deleted?
LogPlayLevel: Error:   08-20 22:38:38.463  5952  5985 D UE4     : [2023.08.20-14.38.38:463][  0]LogProperty: Error: Struct type unknown for property 'StructProperty /Game/VRGK/Blueprints/Player/PlayerCore/BP_VRGamePawn.BP_VRGamePawn_C:SetSteamVRHandCurls:CallFunc_GetFingerCurlsAndSplays_FingerSplays'; perhaps the USTRUCT() was renamed or deleted?
=== Handled ensure: ===
LogPlayLevel: Error:   08-21 18:16:18.725 21242 21468 D UE4     : [2023.08.21-10.16.18:725][  0]LogOutputDevice: Error:
LogPlayLevel: Error:   08-21 18:16:18.725 21242 21468 D UE4     : [2023.08.21-10.16.18:725][  0]LogOutputDevice: Error: Ensure condition failed: (ImageCreateInfo.usage & VK_IMAGE_USAGE_STORAGE_BIT) == 0 [File:D:/Build/++UE4/Sync/Engine/Source/Runtime/VulkanRHI/Private/VulkanTexture.cpp] [Line: 433]
=== Critical error: ===
LogPlayLevel: Error:   08-21 18:16:18.779 21242 21468 D UE4     : [2023.08.21-10.16.18:779][  0]LogAndroid: Error:
LogPlayLevel: Error:   08-21 18:16:18.779 21242 21468 D UE4     : [2023.08.21-10.16.18:779][  0]LogAndroid: Error: Assertion failed: CurrentShadingPath < EShadingPath::Num [File:D:/Build/++UE4/Sync/Engine/Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.h] [Line: 601]
LogPlayLevel: Error:   08-21 18:16:18.779 21242 21468 D UE4     : [2023.08.21-10.16.18:779][  0]LogAndroid: Error:
LogPlayLevel: Error:   08-21 18:16:18.779 21242 21468 D UE4     : [2023.08.21-10.16.18:779][  0]LogAndroid: Error: [Callstack] 0x00000000C4580014 libUE4.so(0x000000000A77E014)!FSceneRenderTargets::GetSceneColorForCurrentShadingPath() const  []
LogPlayLevel: Error:   08-21 18:16:18.779 21242 21468 D UE4     : [2023.08.21-10.16.18:779][  0]LogAndroid: Error: [Callstack] 0x00000000C4588FC4 libUE4.so(0x000000000A786FC4)  []
LogPlayLevel: Error:   08-21 18:16:18.780 21242 21468 D UE4     : [2023.08.21-10.16.18:779][  0]LogAndroid: Error: [Callstack] 0x00000000C435D4A0 libUE4.so(0x000000000A55B4A0)!SetupMobileBasePassUniformParameters(FRHICommandListImmediate&, FViewInfo const&, bool, bool, FMobileBasePassUniformParameters&)  []

原理

【报错】如果Oculus Android运行

从Map_MuseumV3进入,因为地图过大,

读取设备信息还是SteamVR,其他C++资源也未能正确读取,所以报错。从其他地图跳转则正常;

每帧调用,OculusAndroid启动时,初始帧调用默认SteamVR

【无效】添加延迟,地图太大时,读取不到OculusHMD

【无效】添加打包配置,因为根本不是SteamVR

Packing -> Additional Asset Directories to Cook

/Script/SteamVRInputDevice

(有效)启动先加载小地图,再跳转加载大地图

(无效)直接解决方法

Additional Asset Directories to Cook

https://forums.unrealengine.com/t/couldnt-find-file-for-package/447179

for anyone trying to reference a directory inside a Plugin, you can use

UE4: ./../Plugins/ThePlugin/Content/TheDirectory

UE5: /Game/./../Plugins/ThePlugin/Content/TheDirectory

https://blog.csdn.net/qq_18349021/article/details/125321726

Plugins

对比串流和安卓

1.现在OculusLink有线串流启动和steamVR效果是一样的,就是Oculus内的画质比htc vive糊一点,所有地图都正常。

2.然后对于头显android调试运行就离谱,

vrgk_v3默认主地图,头显安卓启动失败;

vrgk_v2默认主地图就可以直接头显安卓启动。

但是如果先头显启动测试地图,再在游戏内跳转回v3的主地图就可以正常运行。

3.安卓启动的测试地图 ,Oculus镜头内直升机和瀑布特效正常;但是森林着火地图点击launch android,项目奔溃。

还未尝试头显启动测试地图再跳转森林着火地图。

4.如果打包到手机,即使是空白地图,手机apk启动也是报错,估计和game instance有关

5 所以真开发打包安卓,要想运行,效果要低,主地图不能大。

相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone4 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui