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](https://www.youtube.com/watch?v=YKXwHYGaCqg "https://www.youtube.com/watch?v=YKXwHYGaCqg") 2024年1月4日 如果说开发 VR 体验时有一件至关重要的话,那就是虚拟手的有效管理。 在这个频道上,我们专门制作了几个视频来探索这个复杂且有时具有挑战性的主题。 结论很明确:尽管这是一个困难的领域,但有商业解决方案可以提供合理的答案。 其中脱颖而出的解决方案之一无疑是 Divor 的"虚拟现实游戏套件",或者更广为人知的名称为 VRGK。 该套件价格实惠,解决了手物理和与环境中物体有效交互等关键问题。 它显着节省了时间和精力,极大地提高了体验的整体质量。 很遗憾,随着虚幻引擎 5 的到来,开发人员决定不再继续该项目。 从他们的角度来看,维护该项目所需的工作量巨大且无利可图。然而,由于社区的努力,Divor 被说服提供社区版本。 这将允许其他人继续他们的工作,幸运的是,这正是发生的事情。 利用三智者季节,还有什么比在我们的项目中使用此套件更好的礼物呢? 此外,我们将着手做出一些小牺牲,以使用 MetaXR 插件将其移植到最新版本的虚幻引擎。 参考资料: ▶ 立体工作室:[https://stereoopticstudios.com/](https://stereoopticstudios.com/ "https://stereoopticstudios.com/") ▶ VRGK - 虚拟现实游戏套件 v3.0:[https://www.unrealengine.com/marketpl...](https://www.unrealengine.com/marketpl... "https://www.unrealengine.com/marketpl...") ▶ 最终公告: https: //redirect.epicgames.com/?redir。 .. ▶ VRGK-社区:[https://github.com/VRGK-Community](https://github.com/VRGK-Community "https://github.com/VRGK-Community") ▶ 社区不和谐: /discord ▶ 旧版文档 PDF: [https://divivor.itch.io/legacy-docs](https://divivor.itch.io/legacy-docs "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](https://www.rstk.cn/news/729695.html?action=onClick "https://www.rstk.cn/news/729695.html?action=onClick") ![](https://i-blog.csdnimg.cn/direct/3e5da505a7c64e08badcb58850583695.png) ![](https://i-blog.csdnimg.cn/direct/c30fa0ef2a0e4367b81059261f840a7c.png) ![](https://i-blog.csdnimg.cn/direct/59e5b14900b34620824550063b800449.png) 跳跃 右手面板下键位 ![](https://i-blog.csdnimg.cn/direct/fe305b1f1fd64488b10e60eb554aa94c.png) ## VRGK 添加Vive按键输入 ![](https://i-blog.csdnimg.cn/direct/1c47a47fe1c842e58917b9b304638d94.png) ![](https://i-blog.csdnimg.cn/direct/a6a94289e43542eea4cb5c3f0ef180f2.png) ## 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 ![](https://i-blog.csdnimg.cn/direct/0f090526bfce4eaa8edd1259319996aa.png) EventGraph 初始化,读取持久存档和全局设置;关闭时,保存存档;关卡启动时,初始化声音 PersistentSaveGameGraph 存档模块,有则读取,无则新建BP_PersistentSaveGameObject对象 SettingsGraph BPO_Settings对象的初始化,并通过settings对象进行参数调用和事件分发监听绑定 ![](https://i-blog.csdnimg.cn/direct/43555b90e36c4540a67638e9397de92f.png) ##### Settings通过方法获取存档配置中的选项 需要调用Setting对象的时候,使用自定义蓝图函数库 BluePrintFunctionLibrary中的Get BPO Game Setting获取Setting对象 ![](https://i-blog.csdnimg.cn/direct/85f84b0079c64714b2e709caadffbeeb.png) BPO_Setting中的方法 ![](https://i-blog.csdnimg.cn/direct/6c800d195a1948c8b83d240191e72711.png) 蓝图函数库中从GameInstance对象中获取其成员Setting实例对象 ![](https://i-blog.csdnimg.cn/direct/e84e4de30943470abddb4868269b6dd3.png) 蓝图函数库中获取GameInstance实例对象 ![](https://i-blog.csdnimg.cn/direct/c684bae3b7ab43958a94c03523cbafed.png) ##### Settings事件分发的call和bind ![](https://i-blog.csdnimg.cn/direct/caccdb7e20c64b2fae65e75026b829cc.png) 获取setting对象后,绑定监听事件分发 UI调用setting对象的方法,其方法中调用了call 绑定监听在具体对象中实现 ![](https://i-blog.csdnimg.cn/direct/c7b8352bde0346bd931643a45b932349.png) BPO_Setting中的定义了方法对事件分发进行了Call调用 ![](https://i-blog.csdnimg.cn/direct/03c15da3e23d4be7a0465c637241e613.png) UI中调用了setting对象的方法 ![](https://i-blog.csdnimg.cn/direct/fc15a143da9043fdbd77a6d214e6e3df.png) #### 存档对象 BP_PersistentSaveGame ![](https://i-blog.csdnimg.cn/direct/f0113115005b4c3ea1e43b042b3da216.png) #### 设置对象 BPO_Settings ![](https://i-blog.csdnimg.cn/direct/699e43b73675485180367a2af8e55543.png) ### 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中创建的一系列对象 ![](https://i-blog.csdnimg.cn/direct/4a2d59a4d3f84fe98c602cf11b57e1fa.png) #### Menu面板 朝向和pawnCamera一致 包裹材质球 Set custom primitive Data Float,Mesh的Render中配置,材质球中也勾选配置 自定义基元数据配置alpha值,这么使用是为了优化减少DrawCall ![](https://i-blog.csdnimg.cn/direct/4714fa716f134746baf7107b955d0c6e.png) ![](https://i-blog.csdnimg.cn/direct/2bc4d014157e4ff0ae1c75bcb0eb14fe.png) 勾上Use Custom Primitive Data则这个参数就不可在材质里修改默认值,同样材质实例里也找不到该参数 传递参数给Custom Primitive Data,编辑器面板在Rendering下面的Custom Primitive Data可以增删相应的数据,蓝图中,有Set Custom Primitive Data从float到Vector4四个函数 ![](https://i-blog.csdnimg.cn/direct/4baf2e0320ab4b008ca433b134f6a690.png) 开启移动端Dynamic Instance,需要在项目配置ini中加一行,把r.Mobile.SupportGPUScene设为1 ![](https://i-blog.csdnimg.cn/direct/9645ef161ca74b1b84e066192b267b43.png) ##### 如何使用 Custom Primitive Data [https://zhuanlan.zhihu.com/p/83529624](https://zhuanlan.zhihu.com/p/83529624 "https://zhuanlan.zhihu.com/p/83529624") ##### 优化UE4性能 、减少DrawCall,材质中使用自定义基元数据 [https://zhuanlan.zhihu.com/p/215545723](https://zhuanlan.zhihu.com/p/215545723 "https://zhuanlan.zhihu.com/p/215545723") #### Spectator 观察者OB模式 切换观察镜头Type,镜头捕获画面2D组件 ![](https://i-blog.csdnimg.cn/direct/bd0e9363f1224c809ee94fee0714c37e.png) ![](https://i-blog.csdnimg.cn/direct/0fdc17e6ae954e1483706302c19d0c70.png) ![](https://i-blog.csdnimg.cn/direct/a54eaddb9f7443d38fb84374918c723a.png) ![](https://i-blog.csdnimg.cn/direct/64f8d89bd4274227a0bb70e71d96c603.png) #### Vignette 黑圈视野 虚影效果 通过黑盒子实现 ![](https://i-blog.csdnimg.cn/direct/f997c66858e44b3aaf063ea963cdbaa1.png) 瞬移,Instant为true,小黑盒被隐藏了则显示出来,小黑圈播放从无到有的动画(延长版),0.05s后,执行0.3s的小黑圈淡出,并隐藏小黑盒 移动,Instant为false,小黑盒被隐藏了就显示小黑盒,并播放淡入动画0.3s复现黑圈; 如果持续移动,则一直执行显示小黑盒,小黑盒已经显示的状态就不继续执行; 最后停止移动执行0.3s的小黑圈淡出,并隐藏小黑盒 黑圈材质为自定义基元数据处理淡入淡出的alpha值 临时显示视野黑圈,在VRGamePawn中被调用 左手前后左右移动 右手左右转向 瞬移 【唯一的瞬息true】 每帧调用 根据角色速度值 ![](https://i-blog.csdnimg.cn/direct/7d8acffbcba1457ebecb6f09effde5df.png) #### 水下镜头 BP_CameraWaterOverlay 自定义基元数据 设置水材质 绑定监听分发事件OnTrackerStateUpdate ![](https://i-blog.csdnimg.cn/direct/ce8f54acded24820a475547259624536.png) ![](https://i-blog.csdnimg.cn/direct/923c4c45ba724e8ea0fa3c651bea8d4b.png) 添加自定义组件BPC_TaggedComponentOverlapTracker,用于注册原始组件Overlap的Tracker事件 在自定义组件中,OverlapBegin添加组件到数组,OverlapEnd则从数组中移除触碰的组件 ![](https://i-blog.csdnimg.cn/direct/5b2cdc1ac4c743fd83f8c85fb7de963c.png) ![](https://i-blog.csdnimg.cn/direct/318d15e5962649409fd95378e3c6c324.png) #### 副标题 BP_VRSubtitles widgetRoot 绝对值scale ![](https://i-blog.csdnimg.cn/direct/1210fb82fe1f4de0b63ba0f31807d4b0.png) scene 绝对坐标 ![](https://i-blog.csdnimg.cn/direct/fc163bf1417348d5a17c7a12d4c0bbb7.png) 定时器每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 ![](https://i-blog.csdnimg.cn/direct/07f2dc65f3c74b58994feee989481c17.png) ![](https://i-blog.csdnimg.cn/direct/6c7c3998c1964badaac0f23acc17dabf.png) UI是进入房间,触碰overlapBegin时执行 ![](https://i-blog.csdnimg.cn/direct/2af6dc5469394b67abaca80fb716ba50.png) ### 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 ![](https://i-blog.csdnimg.cn/direct/b162b630a24d43b3b8a163fe7437a2c9.png) 坐立式体验,则可以设置为eye level 换装功能 1.可通过修改材质实现换装。 2.通过修改Mesh实现换装。1个角色由多个Mesh组成,比如:头,脚,身体,手都是单独的Mesh。它们共用一个骨骼,共用同一个动画蓝图。 如何实现这些Mesh共用同一个动画蓝图呢,参照如下图。 SetMasterPoseComponent 所有的SkeletalMesh共用Mesh节点的动画蓝图。共用动画蓝图节约资源 ![](https://i-blog.csdnimg.cn/direct/6a53d638a0c641e9aba9ada5807ef1ba.png) ![](https://i-blog.csdnimg.cn/direct/ab78fdf47724458bb23466f3811398f5.png) ##### 角色材质通道 Mesh材质球通道,0身体、1logo、2手、3头 ![](https://i-blog.csdnimg.cn/direct/eb06d34dce10437a88dae2b0b785017b.png) Spectator 材质球通道2个,1为胸口logo ![](https://i-blog.csdnimg.cn/direct/f87d7ec5c2ea4b778700ef668f3a769e.png) 消防员材质球通道 0-脸 1-眼 2-脚 3-手和胸 4-玻璃面罩 5-口罩呼吸机 6-头盔 ![](https://i-blog.csdnimg.cn/direct/a17dba7ed3074509b23ee8c487151655.png) ![](https://i-blog.csdnimg.cn/direct/ceefd58fb35d45d4bdeeaa48e920b556.png) ### 工具类 BPFL_GlobalFunctions ![](https://i-blog.csdnimg.cn/direct/78065214e7c24cf4ab34d08af6e4207f.png) ### 动画Anim 标准站立Standing添加了Notify ResetFootPlacement LeftFootPlaced ![](https://i-blog.csdnimg.cn/direct/28f2ad920827453c8c957f5287420fe0.png) 左脚放置之后抬起来, 右脚收回 ![](https://i-blog.csdnimg.cn/direct/3fbbd8f231b5458985d98d1529d7b31d.png) 手指动作 ![](https://i-blog.csdnimg.cn/direct/8037e49893fb48599901cbcb3229aa3b.png) ### 动画蓝图 姿势数据 ![](https://i-blog.csdnimg.cn/direct/2744267a77ee4b459d9b6083ddd0cc2b.png) ## Oculus Android运行 1、只剩双手,身体材质被设置为透明,需要排查 因为源码改为消防员隐藏头部的0通道,变成小白人0通道隐藏身体 2、 OculusLink运行串流 与HTC vive一样执行; 安卓模式: 但是主Map(Map_MuseumV3) 直接Launch Android Quest不行,从其他地图Launch后再进入主Map就可以。 打包同理 3. 直接打包到手机报错 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](https://forums.unrealengine.com/t/couldnt-find-file-for-package/447179 "https://forums.unrealengine.com/t/couldnt-find-file-for-package/447179") ![](https://i-blog.csdnimg.cn/direct/c9e700766c204e4783e11b0e49724109.png) 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](https://blog.csdn.net/qq_18349021/article/details/125321726 "https://blog.csdn.net/qq_18349021/article/details/125321726") ![](https://i-blog.csdnimg.cn/direct/74bff2932b1d47eeaaecc3c708faf84c.png) ![](https://i-blog.csdnimg.cn/direct/c69b6ec9f043481ebaf577d85abfdcdc.png) ##### Plugins ![](https://i-blog.csdnimg.cn/direct/23058eb27e644ac69ea1d6e23af537b7.png) ### 对比串流和安卓 1.现在OculusLink有线串流启动和steamVR效果是一样的,就是Oculus内的画质比htc vive糊一点,所有地图都正常。 2.然后对于头显android调试运行就离谱, vrgk_v3默认主地图,头显安卓启动失败; vrgk_v2默认主地图就可以直接头显安卓启动。 但是如果先头显启动测试地图,再在游戏内跳转回v3的主地图就可以正常运行。 3.安卓启动的测试地图 ,Oculus镜头内直升机和瀑布特效正常;但是森林着火地图点击launch android,项目奔溃。 还未尝试头显启动测试地图再跳转森林着火地图。 4.如果打包到手机,即使是空白地图,手机apk启动也是报错,估计和game instance有关 5 所以真开发打包安卓,要想运行,效果要低,主地图不能大。

相关推荐
white-persist4 小时前
【burp手机真机抓包】Burp Suite 在真机(Android and IOS)抓包手机APP + 微信小程序详细教程
android·前端·ios·智能手机·微信小程序·小程序·原型模式
安卓AndroidQ4 小时前
Android Studio 代码混淆核心解释
android·ide·android studio
qq_7391753694 小时前
Android Studio 实现四则运算+开方+倒数简易计算器
android·python·android studio
就叫飞六吧4 小时前
Android studio -kt构建一个app
android·ide·android studio
qluka6 小时前
Android 窗口结构(三) Home Task 添加Home ActivityRecord
android·开发语言
灿烂阳光g6 小时前
App进程是如何从Zygote中fork出来的
android
谢语花6 小时前
【VS2022】LNK assimp64.lib找不到文件_openframework
android·运维·服务器
model20056 小时前
Android 配置多个 cmake
android
教程分享大师7 小时前
【升级安卓9教程】华为Q21_Q21A_Q21C_Q21AQ_Q21AE_hi3798mv200线刷烧录包带adb权限
android·adb