Mate-Engine 中的 UniVRM 0.x 核心库:VRM 包导入、运行时加载与导出实战指南
桌面应用数字人AI 应用【免费下载链接】Mate-EngineA free Desktop Mate alternative with a lightweight interface and custom VRM support, though with more features.项目地址https://gitcode.com/gh_mirrors/ma/Mate-Engine点击查看免费下载导读本文以Assets/MATE ENGINE - Packages/VRM/README.md为骨架系统讲解 Mate-Engine 仓库内嵌的 UniVRM 0.xcom.vrmc.univrm核心库从 Package Manager /manifest.json两种导入方式到VRMImporterContext的运行时加载管线、glTF_VRM_extensions扩展数据结构、BlendShape / LookAt / 第一人称等 VRM 专属组件再到导出设置参数与测试验证。读完本文你将掌握在 Unity 工程中完整接入并驾驭 VRM 0.x 模型导入、元数据校验、BlendShape 驱动、导出的实战能力并理解 Mate-Engine 项目是如何利用这套库实现自定义 VRM 形象加载的。一、包定位UniVRM-0.XX 的核心库VRM 是VR-ready的 3D 人形 Avatar及模型文件格式建立在 glTF 2.0 之上。本仓库中的 VRM/README.md 开篇即明确其定位The core library for UniVRM-0.XX.即它是 UniVRM 0.x 系列的核心库区别于Assets/MATE ENGINE - Packages/VRM10中的 VRM 1.x 实现。在 Mate-Engine 的资产目录中它位于Assets/MATE ENGINE - Packages/VRM/与Assets/MATE ENGINE - Packages/UniGLTF/、Assets/MATE ENGINE - Packages/VRM10/并列共同构成项目完整的 glTF / VRM 加载能力栈。1.1 包元数据与版本从 package.json 可以确认包的正式身份{ name: com.vrmc.univrm, version: 0.128.3, displayName: VRM, description: VRM importer, unity: 2021.3, dependencies: { com.vrmc.gltf: 0.128.3, com.unity.ugui: 1.0.0 } }要点解读版本0.128.3与com.vrmc.gltfUniGLTF 包版本严格对齐说明二者是同步发布的依赖对Unity 兼容声明unity: 2021.3而 README 的导入说明面向Unity 2019.3.4f1~即该库对 2019.3.4f1 及以上版本保持兼容依赖核心依赖只有com.vrmc.gltfglTF 2.0 导入导出基座与com.unity.ugui关键字vrm、importer、avatar、vr便于 Package Manager 内检索。此外 VRMSpecVersion.cs 中将 VRM 0.x 规范版本固定为0.0Major 0, Minor 0注释明确0 系未实际启用版本字段基本冻结、今后不再变更这正是 VRM 0.x 生态里specVersion恒为0.0的原因。1.2 包内模块划分包内各目录与 Documentation/VRM.md 描述的 UniVRM 组件分层一一对应模块作用仓库中的位置DepthFirstScheduler异步任务调度器由 UniGLTF 提供Assets/MATE ENGINE - Packages/UniGLTF/UniGLTFglTF 2.0 导入器与导出器Assets/MATE ENGINE - Packages/UniGLTF/UniHumanoidUnity Humanoid 工具与 BVH 导入器上述目录中的 Humanoid 相关代码UniJSONJSON 序列化 / 反序列化与 Schema 工具上述目录中的 UniJSON 代码UniVRM本包本体glTF 扩展BlendShape、FirstPerson、LookAt、Meta 等、VRMImporter、VRMExporterAssets/MATE ENGINE - Packages/VRM/Runtime/与Editor/UniVRM 的运行时代码按功能拆分在 Runtime/ 下BlendShape/、FirstPerson/、LookAt/、Meta/、SpringBone/、Format/VRM 扩展的数据结构、IO/导入导出管线、Humanoid/、SkinnedMeshUtility/编辑器侧则在 Editor/ 下提供导出向导、BlendShape 编辑器、验证器等工具Tests/ 目录存放配套的单元测试MToon/目录则内置了 VRM 0.x 默认配套的卡通材质着色器。二、导入 VRM 包Unity 2019.3.4f1~原 README 提供了两种官方推荐的导入方式二者都要求按顺序先导入VRMShaders再导入VRM因为VRM依赖VRMShaders在 UniVRM 上游仓库中二者位于/Assets/VRMShaders与/Assets/VRM两个子路径。2.1 方式一Package Manager 图形界面在 Unity 编辑器中操作Window-Package Manager-Add package from git URL依次添加先添加 VRMShaders 子包对应上游仓库路径/Assets/VRMShaders再添加 VRM 子包对应上游仓库路径/Assets/VRM它会自动依赖前一步的 VRMShaders。注意README 中给出的两个 git URL 均指向 UniVRM 上游仓库vrm-c/UniVRM的对应子路径。由于本仓库已将该包完整内置在Assets/MATE ENGINE - Packages/VRM/下实际使用时也可以直接以本地目录方式引用或按下面方式二在manifest.json中声明。2.2 方式二直接编辑Packages/manifest.json在工程根目录的Packages/manifest.json的dependencies节点中添加两个条目{ dependencies: { com.vrmc.vrmshaders: UniVRM 官方仓库 git URL?path/Assets/VRMShaders, com.vrmc.univrm: UniVRM 官方仓库 git URL?path/Assets/VRM } }要点com.vrmc.univrm会依赖com.vrmc.vrmshaders因此两个条目需要同时声明顺序上建议先写 shaders 再写 univrm若以本地路径引用本仓库内嵌包可将 URL 替换为本地包目录例如file:../../Assets/MATE ENGINE - Packages/VRM之类具体以你工程的实际相对位置为准修改manifest.json后 Unity 会自动解析并加载包无需手动操作。2.3 包自带 Samples根据 package.json 的samples字段该包官方提供 4 个可导入示例安装后可在 Package Manager 中一键导入示例名说明SimpleViewerVRM 运行时加载示例FirstPersonSample多摄像机下的第一人称层示例RuntimeExporterSampleVRM 运行时导出示例AnimationBridgeSampleBlendShape 动画片段示例这些示例与本仓库Assets/MATE ENGINE - Packages/VRM/Tests/SampleTests/中的测试资源相呼应是快速上手 VRM 运行时 API 的捷径。三、运行时加载VRMImporterContext 的五段式管线VRM 0.x 的运行时加载核心类是 VRMImporterContext。它继承自 UniGLTF 的ImporterContext在父类完成 glTF 场景解析后通过OnLoadHierarchy依次执行五个 VRM 专属步骤// 伪代码OnLoadHierarchy 中的关键调用顺序 LoadMetaAsync(awaitCaller); // 1. Meta挂载 VRMMeta读取标题/作者/许可/缩略图 LoadHumanoid(); // 2. Humanoid由 humanoid.bone 映射生成 Unity Avatar LoadBlendShapeMaster(awaitCaller); // 3. BlendShape把 blendShapeGroups 转成 BlendShapeClip 资源 VRMSpringUtility.LoadSecondary(...); // 4. SecondaryAnimation重建 SpringBone 骨骼摆动 LoadFirstPerson(awaitCaller); // 5. FirstPerson挂载 VRMFirstPerson 与 VRMLookAtHead每个步骤之间都会await awaitCaller.NextFrame()把耗时操作分摊到多个帧避免加载大模型时阻塞主线程。各步骤的实现要点均可从源码确认LoadMetaAsync创建VRMMetaObjectScriptableObject把meta中的title、author、version、contactInformation、reference、许可字段逐一写入并通过GltfTextureImporter.TryCreateSrgb异步解码缩略图gltfMeta.texture 0时才会尝试否则跳过LoadHumanoid通过VRM.humanoid.ToDescription(Nodes)生成AvatarDescription再用AvatarDescription.CreateAvatar(Root.transform)创建 UnityAvatar若!HumanoidAvatar.isValid || !isHuman会直接抛异常随后在 Root 上挂载VRMHumanoidDescription与Animator并把所有SkinnedMeshRenderer的probeAnchor设为头部骨骼以保证光照探针跟随头部LoadBlendShapeMaster遍历blendShapeMaster.blendShapeGroups把每个分组转换为BlendShapeClip含BlendShapeBinding骨骼绑定与MaterialValueBinding材质值绑定最终挂载VRMBlendShapeProxy并调用CreateDefaultPreset()补齐预设LoadFirstPerson读取firstPerson.firstPersonBone找不到时走SetDefault()兜底随后为 Root 挂载VRMFirstPerson和VRMLookAtHead并通过OnImported根据lookAtType选择 Bone 或 BlendShape 两种视线实现。值得注意的一个实现细节LoadBlendShapeBind在还原材质绑定时会剥离_ST_S/_ST_T后缀VRM 0.x 材质属性名的历史遗留写法并依据目标材质的当前颜色值记录BaseValue供 BlendShape 在 OnDestroy 时还原材质初始值。3.1 资源所有权与释放VRMImporterContext还实现了TransferOwnership与Dispose前者把HumanoidAvatar、Meta、AvatarDescription、所有BlendShapeClip与BlendShapeAvatar的所有权移交给调用方后者则反向销毁这些对象。Mate-Engine 的加载器正是利用这一机制配合GltfInstanceDisposer见后文在模型销毁时释放整个运行时实例。四、VRM 扩展数据结构glTF_VRM_extensionsVRM 0.x 的所有专属信息都存放在 glTF 文件的extensions.VRM节点里。数据结构定义见 glTF_VRM_extensions.cs扩展名常量ExtensionName VRM包含六个子对象字段对应数据结构内容metaglTF_VRM_Meta模型标题、作者、版本、缩略图、使用许可humanoidglTF_VRM_Humanoid人类骨骼映射HumanBone 到节点索引firstPersonglTF_VRM_Firstperson第一人称头骨、视线类型与 mesh 注释blendShapeMasterglTF_VRM_BlendShapeMasterBlendShape 分组预设、绑定、材质值secondaryAnimationglTF_VRM_SecondaryAnimationSpringBone 摆骨组与碰撞体组materialPropertiesListglTF_VRM_Material材质属性渲染模式、着色器等此外还保留exporterVersion如UniVRM-0.128.3与冻结的specVersion。反序列化入口为TryDeserialize遍历glTFExtensionImport中的键命中VRM即调用生成的VrmDeserializer.Deserialize完成解析。在导出侧VRMExporter.cs 的ExportExtensions会反向执行从VRMHumanoidDescription读取骨骼映射并写入VRM.humanoid遍历VRMBlendShapeProxy.BlendShapeAvatar.Clips写入blendShapeMaster调用VRMSpringUtility.ExportSecondary写入secondaryAnimation读取VRMMeta/ 兼容旧版VRMMetaInformation写入meta读取VRMFirstPerson与VRMLookAtHead写入firstPerson最后为每个材质导出materialProperties并通过VRMSerializer.Serialize序列化为 JSON 字节挂到 glTF 的extensions上。4.1 Meta许可信息的完整字段glTF_VRM_Meta.cs 是 VRM 0.x 许可体系的载体字段如下基础信息title、version、author、contactInformation、reference、texture缩略图索引-1表示未指定使用许可Usage PermissionallowedUserOnlyAuthor仅作者/ExplicitlyLicensedPerson明确授权者/Everyone所有人violentUssage、sexualUssage、commercialUssage均为Disallow/Allow二选一otherPermissionUrl超出上述条款的其他条件说明链接分发许可Distribution LicenselicenseType枚举包括Redistribution_Prohibited、CC0、CC_BY、CC_BY_NC、CC_BY_SA、CC_BY_NC_SA、CC_BY_ND、CC_BY_NC_ND、Other选择Other时必须填otherLicenseUrl。Mate-Engine 的 VRM 加载器在模型导入后正是读取这些字段来展示作者、版本与许可信息见第六节。五、VRM 专属运行时组件5.1 BlendShape 代理VRMBlendShapeProxyVRMBlendShapeProxy 挂载在模型 Root 上持有BlendShapeAvatar一组BlendShapeClip对外提供统一的表情驱动 APIImmediatelySetValue(key, value)立即设置某个 BlendShape 的权重并生效AccumulateValue(key, value)累加权重之后需调用Apply()统一提交适合同时驱动多个表情GetValue(key)/GetValues()查询当前权重SetValues(values)/Apply()批量设置并提交Reinitialize()在修改BlendShapeAvatar.Clips后重建内部 merger。驱动时使用的BlendShapeKey可通过预设BlendShapePreset如 Happy / Angry / Blink 等或自定义名称CreateUnknown构造。注意OnImported在运行时实现中会直接抛出NotImplementedException——这是因为运行时该组件由VRMImporterContext直接组装见 3.1OnImported仅保留给编辑器导入流程这正是源码注释所强调的OnImported 与 Start 的分工。5.2 视线追踪VRMLookAtHead 与两种 ApplyerVRMLookAtHead 负责把目标物体的世界坐标换算成头部骨骼局部坐标下的 Yaw / Pitch 角并通过YawPitchChanged事件广播。它的OnImported会根据firstPerson.lookAtType自动挂载两种实现之一VRMLookAtBoneApplyerLookAtType.Bone通过旋转骨骼实现视线导出时读取HorizontalInner、HorizontalOuter、VerticalDown、VerticalUp四个角度曲线VRMLookAtBlendShapeApplyerLookAtType.BlendShape通过 BlendShape 权重实现视线导出时读取水平外角与上下俯仰两组曲线。组件还提供UpdateTypeNone/Update/LateUpdate选择在哪个生命周期更新视线以及CreateThumbnail()用临时相机渲染 2048×2048 头像缩略图的能力导入 Meta 缩略图缺省时可由编辑器触发补生成。5.3 第一人称裁剪与 SpringBoneVRMFirstPersonRuntime/FirstPerson/按头骨与 Renderer 的firstPersonFlag对渲染器分层配合VRMFirstPersonCameraManager实现 VR 场景中第一人称时不显示自己头部的标准做法SpringBoneRuntime/SpringBone/则是头发、裙子等部位的自然摆动物理模拟运行时由Vrm0XSpringBoneDefaultRuntime在导入时初始化。六、导出菜单、向导与参数详解6.1 编辑器菜单入口VrmTopMenu.cs 把 VRM 0.x 的编辑器功能统一挂到VRM顶级菜单下VRM/Export VRM 0.x...打开导出向导VRM/Import VRM 0.x...从.vrm文件导入VRM/MeshIntegrator...网格整合向导VrmMeshIntegratorWizardVRM/Freeze T-Pose把模型强制规范化为 T-PoseVRMHumanoidNormalizerMenu.NormalizeVRM/Save SpringBone to JSON/Load SpringBone from JSONSpringBone 配置的 JSON 存取工具。6.2 导出向导的四个标签页VRMExporterWizard 实现Export VRM 0.x...向导分为Meta、Mesh、BlendShape、ExportSettings四个页签Meta编辑VRMMetaObject若场景 Root 已挂VRMMeta则复用否则使用临时实例对应上文的许可字段Mesh通过MeshExportValidator检查网格/Renderer、顶点色与材质VRMMaterialValidator的合规性BlendShape允许在导出前对场景中的模型应用某个BlendShapeClipBake 当前权重或一键 ClearExportSettings设置 VRMExportSettings 中的导出参数。导出前向导会执行一串校验器ValidatorFactoryHierarchy 校验、Mesh/Renderer 校验、Humanoid 规范化与 T-Pose 校验、VRM 专用校验ReduceBlendshape相关、SpringBone 校验、FirstPerson 校验、BlendShapeProxy 校验、Meta 校验——任一不通过都无法导出。最终ExportPath调用VRMEditorExporter.Export写出.vrm文件若输出到 Assets 目录内还会自动触发AssetDatabase.ImportAsset完成资源导入。6.3 VRMExportSettings 参数速查参数默认值作用与注意事项ForceTPosefalse导出时强制把模型摆成 T-PosePoseFreezetrue导出时对层级做归一化冻结姿势仅首次导出建议开启FreezeMeshUseCurrentBlendShapeWeighttrue冻结网格时以当前 BlendShape 权重作为基础形态UseSparseAccessorfalse用 Sparse Accessor 序列化 BlendShape可减小 VRM 文件体积OnlyBlendshapePositionfalse只导出 BlendShape 的 PositionUniVRM-0.54 及以后才能加载否则加载失败ReduceBlendshapefalse删除未被 BlendShapeClip 引用的 BlendShapeReduceBlendshapeClipfalse删除 Preset 为 Unknown 的 BlendShapeClipDivideVertexBufferfalse导出时按 submesh 拆分顶点缓冲提升 glTF 兼容性KeepVertexColorfalse保留顶点色特殊用途KeepAnimationfalse保留动画特殊用途其中GltfExportSettings属性把这些布尔项映射为 UniGLTF 导出配置。另需注意 VRMExporter 对坐标轴有硬性要求VRM 0.x 规范要求InverseAxis为Axes.Z不匹配时导出器会打印警告迁移场景允许 reverseX。七、测试验证导入-导出-再导入的往返闭环Tests/VRMLoadTests.cs 展示了库本身的测试策略也即推荐的验证思路通过GlbFileParser或GlbLowLevelParser解析.vrmGLB 容器文件用VRMImporterContext(new VRMData(data))导入得到GameObject用VRMExporter.Export(new GltfExportSettings(), go, new EditorTextureSerializer())重新导出对导出的字节ToGlbBytes()再次导入形成导入 → 导出 → 再导入的往返测试确保序列化不丢信息。测试还依赖环境变量VRM_TEST_MODELS指向的模型目录进行批量遍历。同一目录下还有 UniVRMSerializeTests.cs、VRMLookAtTests.cs、VRMBlendShapeKeyTest.cs 等针对序列化、视线与 BlendShape Key 的专项测试可作为接入库后自测的参考范本。八、在 Mate-Engine 中的实际集成VRM 0.x 加载链路仓库的 VRMLoader.cs 是这套库在项目中的直接消费者清晰地展示了生产环境的加载策略启动时从SaveLoadHandler/PlayerPrefs恢复上次选择的模型路径若开启enableRandomAvatar则随机选择一个 Avatar默认模型 / DLC /avatars.json中的历史模型打开文件对话框选择模型支持vrm/me/prefab三种扩展名加载.vrm时优先尝试 VRM 1.xVrm10Importer失败后回退到 VRM 0.x 的VRMImporterContext// VRMLoader.cs 中的回退逻辑简化 using var gltfData new GlbBinaryParser(fileData, path).Parse(); using (var importer new VRMImporterContext(new VRMData(gltfData))) { var instance await importer.LoadAsync(new ImmediateCaller()); loadedModel instance.Root; loadedModel.AddComponentGltfInstanceDisposer().Bind(instance); }加载成功后FinalizeLoadedModel会停用默认模型、将新模型挂到customModelOutput下并归零变换、启用所有SkinnedMeshRenderer、从模板 Prefab 注入项目自定义组件InjectComponentsFromPrefab通过反射拷贝字段、通知MEValueChanger.TryAttachCustomVRM、读取元数据VRM 0.x 取VRMMeta.Meta的Title/Author/Version/Thumbnail并登记进AvatarLibraryMenu的 Avatar 库、统计多边形数GltfInstanceDisposer在OnDestroy时调用RuntimeGltfInstance.Dispose()配合ReleaseRamAndUnloadAssetsCoResources.UnloadUnusedAssets 双次GC.Collect完成模型切换时的内存回收。从这段集成代码可以看出VRM 0.x 库在本项目中的角色是双版本兼容加载策略中的兜底路径与 VRM10 包互为补充共同支撑自定义 VRM 形象这一核心功能。九、注意事项与已知限制规范版本冻结specVersion恒为0.0VRM 0.x 规范不再演进新项目建议评估 VRM 1.x仓库内Assets/MATE ENGINE - Packages/VRM10/渲染管线包内置 MToon 材质编辑器侧提供Switch to built-in RenderPipeline等开发菜单VRM_DEVELOP宏控制仅开发构建可用接入 URP/HDRP 时需关注材质兼容导出兼容OnlyBlendshapePosition导出的文件要求 UniVRM-0.54 及以上才能加载对旧版用户需谨慎开启坐标轴导出时InverseAxis必须为Axes.Z否则仅打印警告、可能产生姿态偏差异步模型导入采用逐帧分摊NextFrame的异步策略ImmediateCaller适用于运行时即时加载正式场景可传入自定义IAwaitCaller控制加载节奏。结语Assets/MATE ENGINE - Packages/VRM/目录完整内嵌了 UniVRM 0.x0.128.3核心库包级依赖清晰、运行时导入导出管线五段分明、VRM 扩展数据结构完整、编辑器向导与校验器齐备并配有往返测试守护序列化正确性。在 Mate-Engine 中它与 VRM10 包协同为自定义 VRM 形象加载提供了双版本兜底方案。开发者既可以按 README 的两种方式把该包接入自己的 Unity 工程也可以直接参考本仓库的加载链路在自己的应用中复刻一套健壮的 VRM 0.x 模型接入流程。赞分享桌面应用数字人AI 应用【免费下载链接】Mate-EngineA free Desktop Mate alternative with a lightweight interface and custom VRM support, though with more features.项目地址https://gitcode.com/gh_mirrors/ma/Mate-Engine点击查看免费下载相关推荐完整指南UniVRM在Unity中的VRM模型导入与导出完整指南UniVRM在Unity中的VRM模型导入与导出 UniVRM是一个基于glTF的VRM格式实现专为Unity引擎设计。VRM格式作为3D虚拟形象文图形学3D渲染UniVRM完整使用指南从安装到VRM模型导入导出的终极解决方案UniVRM完整使用指南从安装到VRM模型导入导出的终极解决方案 UniVRM是基于glTF标准的VRM格式实现专为Unity引擎设计的开源项目。作为VRM图形学3D渲染Notepad-- 完整上手指南乱码、批量替换、双文件对比一次搞定Notepad 完整上手指南乱码、批量替换、双文件对比一次搞定 从旧机器拷来的 txt 打开就是一屏问号Notepad 是一款 GPL 开源、基于 Qt5桌面应用数字人AI 应用上一篇使用 plasmicapp/auth-react 为 Plasmic 应用接入登录认证与用户会话管理下一篇DeepSpeech 贡献指南从高质量 Pull Request 到通过代码评审的完整实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考