realvirtual 做数字孪生开发时,CAD 数据的导入经常是第一个卡住团队的地方。尤其是手上拿着整套设备模型、几十个装配体、几百个零件,想在 Unity 里把它们变成可交互、带运动关系的数字孪生场景,如果每个模型都靠手动拖拽、手动对准、手动调材质,时间会无限拉长。realvirtual 这个基于 Unity 的数字孪生开发平台,核心价值之一就是把 CAD 数据到 Unity 场景的链路做通,而这篇教程要讲的就是:如何让大型 CAD 数据自动进入到 realvirtual 平台里,减少重复劳动,让导入过程可重复、可批量、可维护。
先说结论:大型 CAD 数据导入的重点不是“能不能导入”,而是“如何稳定地、有计划地导入”。如果你只有几个小零件,手工导入完全没问题;但当模型数量超过几十个,或者单模型面数达到几十万甚至上百万,就必须在导入前做好格式转换、数据轻量化和命名规范。下面按实际落地顺序拆开讲。
1. 先搞清楚 realvirtual 的 CAD 导入到底解决什么问题
1.1 大型 CAD 数据导入为什么不能靠手工
很多刚从 SolidWorks、NX、CATIA 或其他 CAD 软件转到 Unity 的人,第一反应是直接把模型导出成 FBX,然后拖进 Unity。这个思路对单个简单模型没问题,但放到数字孪生场景里就会出现几个明显问题。
第一个问题是模型层级丢失。CAD 里的装配体有严格的父子关系,例如“电机”下面有“端盖”、“转子”、“轴承”,轴承里又有“滚珠”。直接导出 FBX 再拖进 Unity,很多时候层级会变成一层平铺的 Mesh,或者父子关系被简化掉,导致后续想在 realvirtual 里给某个部件挂运动脚本、挂传感器逻辑时,根本找不到对应节点。
第二个问题是坐标轴不一致。CAD 软件里建模时,模型的原点和方向取决于建模习惯。有些工程师喜欢把原点放在零件中心,有些放在边角,有些直接按全局坐标系摆放。导入 Unity 后,模型要么偏移一大截,要么旋转 90 度,还得在编辑器里一个个手动修正。零件少还能忍,零件一多就成了灾难。
第三个问题是资源占用。CAD 原生文件里往往包含非常精细的曲面、圆角、倒角,这些几何数据在 CAD 显示软件里很流畅,但导入 Unity 后,动辄几百万三角形的 Mesh 会让编辑器卡顿,甚至直接崩溃。
realvirtual 解决的方向,不是替你把 CAD 原生文件直接读进来,而是提供一套“从 CAD 到 Unity 再到可仿真对象”的导入路径和自动化机制。它能帮你把外部模型、运动关系、内部对象结构整理成统一结构,再通过脚本批量处理。
1.2 realvirtual 自动导入的适用场景和边界
先说适用场景。最适合用自动导入的,是模型数量大、结构重复、需要定期更新数据的项目。比如:
- 工厂产线数字孪生,需要导入整条生产线的设备模型。
- 物流仓储仿真,需要把货架、输送机、AGV 等模型批量导入。
- 机器人工作单元,需要把机器人本体、夹具、外围设备按装配关系导入。
- 设备运维孪生,CAD 模型随设计改动要定期重新导入。
这些场景里,模型不是一次性的,后续设计变更后要再次导入。如果第一次用手工方式整理,第二次还得重新手工整理,非常浪费人力。自动化的价值就在于:源模型更新后,脚本能按固定规则重新转换、重新导入、重新匹配,整个过程尽可能少人工干预。
边界也要说清楚。realvirtual 不是万能转换器,它不会把任何 CAD 格式都自动识别成带运动关系的数字孪生对象。原始 CAD 里的装配关系、运动副、约束条件,需要在导出时做一定设置,或者导入后用组件去匹配。另外,如果原始 CAD 模型精度极高、文件极大,导入前必须做轻量化处理,这个步骤不能省。低配机器能导入小模型不代表能批量处理大型总成,实际项目里要把单模型面数和总模型数量都控制在一个合理范围。
2. 自动导入前,先把环境和数据格式准备好
2.1 Unity 与 realvirtual 的基础环境
realvirtual 是运行在 Unity 基础上的数字孪生开发平台,所以前置环境必然是 Unity 编辑器。安装 realvirtual 插件的方式一般是通过 Unity Asset Store 或官方包导入,导入后会看到 realvirtual 的菜单、组件库和示例场景。
建议在动手导入大型 CAD 数据之前,先把 realvirtual 的示例场景完整跑一遍,确认以下几点都正常:
- Unity 能正常创建 3D 项目。
- realvirtual 包导入完成后菜单能正常显示。
- 示例场景能进入 Play Mode,并且能看到实时数据读取。
- 你的 Unity 版本和 realvirtual 版本兼容。
如果示例场景都跑不起来,先不要急着倒 CAD,因为后面所有报错都会混在环境问题里,很难排查。版本方面,原始资料没有给明确版本号,建议以你实际安装的 Unity 版本和 realvirtual 版本为准,先确认依赖兼容性。
注意:不要一上来就导入整个大型 CAD 总成,先用一个小零件跑通全流程。环境、转换、导入、验证,这四个环节都正常后,再放大模型。
2.2 CAD 源文件格式与转换链路
realvirtual 本身不直接解析 CATIA、NX 的原生格式。Unity 能直接识别的是 FBX、OBJ、glTF 等常见 3D 格式。所以从 CAD 到 realvirtual 的转换链路通常是:
- CAD 原生文件(如 SLDPRT、STEP、IGES、CATPart)→ 导出为中间格式(如 STEP、IGES)。
- 中间格式 → 转换为 FBX 或 glTF。
- FBX 或 glTF → 导入 Unity。
- Unity 内通过 realvirtual 组件进行装配和运动配置。
这里最容易踩坑的是第一步。CAD 软件里直接“另存为 FBX”有时并不能得到最好的结果,因为 FBX 主要面向 DCC 工具(3ds Max、Maya、Blender),对 CAD 装配体支持有限。更稳的做法是:
- 先从 CAD 软件导出为 STEP 或 IGES,尽量保留装配结构。
- 使用专业转换工具把 STEP/IGES 转成 FBX。
- 如果 CAD 软件支持,也可以使用 CAD 软件自带的 VRED、3DEXPERIENCE 等插件做转换,但需要额外安装。
另一个常见做法是先把 CAD 模型导入 Blender,再在 Blender 里检查并导出为 FBX。Blender 的好处是可以顺便处理轴心、材质、命名,而且免费。但注意,Blender 导入 STEP 通常也需要插件,比如 CAD Sketcher 或 StepUp 等,需要提前装好。原始材料没有提及具体插件,这里只是给出通用实践路径。
2.3 数据轻量化:大型模型必须处理的三个问题
大型 CAD 模型进入 Unity 前,数据轻量化这一步非常关键,直接影响后续所有操作。
第一个问题是面数。一个精密零件可能就有几十万面,整机装配可能上千万面。Unity 虽然能渲染很多面数,但数字孪生场景通常还要跑 PLC 通信、动画、UI、物理仿真,资源不是只给渲染用的。建议把单模型面数控制在 5 万到 20 万以内,复杂大件可以拆分成多个子网格,或者用减面工具处理。
第二个问题是贴图。CAD 模型里很多是外观颜色,不是真正的贴图。转换成 FBX 后,颜色信息可能变成材质颜色,也可能丢失。如果有真实贴图,要确保贴图文件路径正确,Unity 导入时能识别。
第三个问题是模型数量。一个数字孪生场景里,如果模型数量过多,即使每个模型面数不高,也会因为 Draw Call 太多而导致性能下降。导入前要对模型进行合并规划:哪些零件需要独立控制,哪些可以合并成一个静态网格。
判断标准很简单:如果 Unity 编辑器在导入后操作卡顿,或者在 Play Mode 下帧率很低,优先检查总三角形数量和场景里 GameObject 数量,而不是怀疑 realvirtual 有问题。
3. 从 CAD 原始文件到 Unity 可识别资源的完整流程
3.1 原始 CAD 格式转换
假设你手里有一整套设备模型,原始文件是 STEP 格式。第一步是把它转成 FBX。
我一般会先建一个统一的“转换目录”,例如:
D:/DigitalTwinProject/SourceCAD/ D:/DigitalTwinProject/ConvertedFBX/ D:/DigitalTwinProject/UnityProject/Assets/Models/转出来的 FBX 文件统一放在 ConvertedFBX 目录,文件名遵循“设备编号_部件名称”的规则,方便后续脚本处理。转换时注意几个参数:
- 单位:CAD 里常用毫米,Unity 里默认单位是米,导出时需要统一,否则模型大小会差 1000 倍。
- 坐标系:CAD 常用 Y 轴向上或 Z 轴向上,Unity 是 Y 轴向上。导出时把 Z-up 转换成 Y-up,避免模型躺倒。
- 轴心:尽量把轴心放在部件中心或装配基准点,后续在 realvirtual 里做运动配置会更方便。
如果转换工具支持批量转换,可以一次处理多个文件。没有现成转换工具时,用 Blender 的 Python 脚本也能实现批处理,核心逻辑无非是“读取 STEP → 清理场景 → 导出 FBX → 清空场景 → 处理下一个”。
3.2 在 Unity 中创建导入工程和资源目录
Unity 工程里的目录结构建议提前规划好。一个比较干净的结构是:
Assets/ Models/ Equipment01/ Equipment02/ Scenes/ Scripts/ realvirtual/把 FBX 文件放进 Assets/Models/Equipment01 后,Unity 会自动导入。首次导入可能需要一点时间,尤其当 FBX 文件较大时,Unity 会生成对应的材质和网格资源。导入完成后,不要急着拖到场景里,先检查资源导入设置。
在 Unity 的 Inspector 里选中 FBX 文件,重点检查:
- Scale Factor:是否为 1,或者按照你设定的单位换算。
- 是否勾选 Read/Write Enabled:如果模型需要在运行时动态变换,可能要保持开启,但会额外占用内存。
- Generate Colliders:如果 realvirtual 里要用到物理碰撞,可以生成,但大型模型建议手动配置简单碰撞体。
- 材质导入:确认材质是否能正确识别。
如果 FBX 包含多个子网格,Unity 会保留层级。在层级列表里能看到类似 设备01/部件A/部件B 的结构,这为后续 realvirtual 运动配置提供了基础。
3.3 使用 realvirtual 的工业对象和组件进行装配
realvirtual 平台里,数字孪生对象大多是通过组件组合实现的。简单说,一个设备对象会有运动学组件、PLC 连接组件、传感器组件等。CAD 模型导入后,不会自动变成 realvirtual 对象,需要把 FBX 模型挂到 realvirtual 的工业对象组件下。
通常的做法是:
- 在 Unity 层级里创建一个空 GameObject,命名为 “机器手臂_01”。
- 给该 GameObject 挂 realvirtual 的相关驱动组件,例如驱动旋转轴、线性轴或关节的组件。
- 把 FBX 模型作为子物体拖到这个 GameObject 下面。
- 在模型内部,把需要旋转或移动的子节点与驱动组件关联。
这里最关键的判断是:哪些 CAD 零件对应运动轴,哪些是静态外观件。比如机器人,基座、腰关节、大臂、小臂、腕部,每个运动部分应该对应一个轴。原始 CAD 的装配树里通常已经有这些层级,转换后尽量保留,否则你就要在 Unity 里手动拆分。手动拆分非常痛苦,所以转换环节一定要检查装配结构是否保留。
如果你的 CAD 模型层级确实丢了,也不要绝望,可以在 FBX 导入设置里开启拆分网格选项,或者在 Blender 里重新调整层级后再导出。但最好还是在 CAD 导出这一步就把装配体结构处理好,因为越往后修,成本越高。
4. 让导入过程自动化:脚本、批处理和命名规则
4.1 自动化脚本的核心逻辑
当模型数量多了以后,手工在 Unity 里拖资源、挂组件、设置父子关系是重复劳动。自动化的核心不是写一个万能导入器,而是把“重复的、有固定规则的操作”变成脚本。
常见的自动化逻辑分三层:
第一层:资源导入自动化。把 FBX、glTF 等文件放在固定目录后,通过 Unity Editor 脚本批量导入,并自动设置导入参数,比如 Scale Factor、材质类型、碰撞体设置。Unity 里可以用 AssetPostprocessor 或 EditorApplication.delayCall 实现。
第二层:场景装配自动化。根据一个配置表(CSV、JSON 或 ScriptableObject),自动创建 GameObject、挂载 realvirtual 组件、设置父子关系、指定运动轴。配置表里每一行代表一个设备,字段包括设备名称、FBX 路径、初始位置、旋转、是否可运动、关联轴名称等。
第三层:数据映射自动化。把 realvirtual 的可控参数和外部数据源(PLC、数据库、Web API)对应起来,避免每个参数都手工绑定。这一步已经是完整的数字孪生逻辑配置,但和导入的关系仍然密切:模型节点命名不规范,后续所有映射都会乱掉。
一个典型的 JSON 配置表样例如下:
[ { "DeviceID": "Robot_Arm_01", "FBXPath": "Assets/Models/Robot_Arm_01.fbx", "Position": [0, 0, 0], "Rotation": [0, 0, 0], "Scale": [1, 1, 1], "Axis": ["Base", "Shoulder", "Elbow", "Wrist"], "IsStatic": false }, { "DeviceID": "Conveyor_Belt_01", "FBXPath": "Assets/Models/Conveyor_Belt_01.fbx", "Position": [10, 0, 0], "Rotation": [0, 0, 0], "Scale": [1, 1, 1], "Axis": ["DriveRoller"], "IsStatic": false } ]脚本读这个配置后,自动完成导入、实例化、挂组件。这样后续如果模型更新,只需要替换 FBX 文件、改配置表里的路径,然后重新跑一遍脚本即可。
4.2 批量导入时的命名和层级规范
自动化最怕的就是命名不统一。如果 CAD 模型里有的叫 “Part1”,有的叫 “未命名”,有的包含特殊字符,脚本很难稳定匹配。建议在 CAD 转换前就建立一套命名规范:
- 设备命名:设备类型_编号,例如 Robot_01、Conveyor_02。
- 部件命名:设备编号_部件名,例如 Robot_01_Base、Robot_01_Shoulder。
- 轴命名:最好用 realvirtual 能识别的英文名称,例如 Axis1、Joint1,避免中文和空格。
- 统一后缀:所有可运动部件带
_DYN后缀,所有静态部件带_STATIC后缀,方便脚本识别。
命名规范的作用,不是让你看着舒服,而是让脚本和 realvirtual 组件能自动匹配。比如脚本遍历配置表时,只要发现_DYN后缀的节点,就自动给它找对应运动组件;只要发现设备名称匹配,就把它放到正确的父节点下。这个规则越严格,自动化越稳定。
4.3 材质映射与轴心矫正
材质是自动化导入里最容易出问题的环节。CAD 模型的材质通常是 PBR 材质,但导出成 FBX 后,材质命名、贴图路径可能发生变化。Unity 导入时会自动生成默认材质,但默认材质往往不是最终效果。
一个省事的做法是:在转换工具里把材质导出为标准 PBR 参数,然后在 Unity 的资源文件夹里维护一张“材质映射表”,例如:
| CAD 材质名 | Unity 材质名 | 说明 |
|---|---|---|
| Steel_01 | Mat_Steel_01 | 机架和结构件 |
| Aluminium_02 | Mat_Aluminum_02 | 轻量化外壳 |
| Rubber_03 | Mat_Rubber_03 | 减震垫 |
自动化脚本在导入 FBX 后,遍历所有子网格,根据材质名替换成对应的 Unity 材质。这样即使模型更新了,材质表现也能保持一致。
轴心矫正同样可以脚本化。很多 CAD 模型的轴心不在 Unity 期望的位置,导致旋转动画很怪。常用的方式是:在脚本里获取节点包围盒,把轴心移动到包围盒底部中心、中心或某个设定点。具体移动到哪,取决于这个部件怎么运动。比如旋转轴通常希望轴心在旋转中心线上,线性移动轴希望轴心在移动起点。这些可以通过配置表里的PivotType字段控制。
5. 大型模型导入性能优化:LOD、碰撞体与资源占用
5.1 LOD 和网格简化
大型 CAD 模型导入数字孪生平台后,最直接的问题是渲染性能。一个真实的产线场景可能有几十台设备,每台设备几十万个三角形,总面数轻松超过几百万。即使显卡能扛住,Unity 编辑器也会很卡,开发者没法正常工作。
解决办法是 LOD(Level of Detail)。为每个模型准备多个精度等级:近距离用高精度模型,远距离用低精度模型。Unity 的 LOD Group 组件可以在运行时自动切换。自动导入流程里,最好一并生成 LOD 层级。
生成 LOD 有两种方式:
- 使用 Blender 或专业减面工具,预先生成 3 个精度等级的 FBX,分别对应 LOD0、LOD1、LOD2。
- 在 Unity 中用 SpeedTree 或 Mesh Baker 等工具自动生成简化网格,但效果不一定稳定。
我个人更推荐第一种。因为在转换阶段生成多个精度版本,可以把“减面”这个耗时操作放在导入 Unity 之前,不让 Unity 编辑器承担太多负担。文件命名可以带上精度后缀,例如:
Robot_01_LOD0.fbx Robot_01_LOD1.fbx Robot_01_LOD2.fbx导入后,脚本自动把这三个模型挂到同一个 LOD Group 下,LOD0 在近处显示,LOD2 在远处显示。这样既能保证近景细节,又能保证整机帧率。
5.2 碰撞体策略
数字孪生场景里,很多操作需要物理碰撞。叉车要停在指定位置,AGV 要避障,机器手抓取时要检测碰撞。但如果每个 CAD 网格都生成精密的 MeshCollider,性能会非常差。
好的策略是:
- 静态设备(机架、护栏、地面、墙)使用 BoxCollider 或 CapsuleCollider 组合,不要用精确 MeshCollider。
- 运动部件使用简单的 BoxCollider,包围盒可以略大于实际网格,减少碰撞计算量。
- 需要精确抓取或探测的表面,才使用 MeshCollider,并且要控制该网格的面数。
自动化导入时,可以在配置表里指定每个设备的碰撞体类型。脚本根据类型自动添加碰撞体组件,并自动设置大小和位置。这样既保证了物理效果,又不会让性能崩掉。
5.3 运行时实例化与场景分割
如果模型数量真的非常大,比如一个大型园区级数字孪生,把全部模型都放在一个场景里,即使有 LOD 也可能卡顿。这时候要把场景拆分成多个 SubScene 或使用地址加载。
Unity 的 Addressables 可以按需加载模型:只有玩家视角靠近时才加载高精度资源,离开时卸载。realvirtual 相关的设备和脚本也可以放在同一个 Addressable Group 里,用加载回调初始化驱动组件。
自动导入脚本可以额外生成一份 Addressables 配置,或者把模型资源标记为 Addressable。这样,CAD 模型多不再是负担,加载逻辑由运行时视角决定。这个做法适合真正的大型项目,如果只是单条产线或单台设备,场景拆分的收益不大,不用为了复杂而复杂。
注意:如果只是学习用途,默认配置通常够用。先跑通第一版,再根据性能和数据量决定要不要上 LOD 和 Addressables。一上来就把架构做得很重,反而会拖慢项目进度。
6. 常见问题排查和经验总结
6.1 导入后模型位置偏移或轴心错误
这是 CAD 导入 Unity 最常见的现象。模型不在原点,或者旋转方向不对。处理顺序是:
- 先看 FBX 导入设置里的 Scale Factor 和旋转设置。
- 再到 CAD 转换工具里检查原点和坐标系。
- 最后看 Unity 里模型包围盒的中心位置。
如果是脚本导入,检查配置表里的 Position 和 Rotation 字段是否写对。不要直接改模型坐标,因为 CAD 更新后重新导入,所有手工坐标修正都会丢失。正确做法是在转换阶段统一调整轴心和原点。
6.2 材质丢失、贴图发紫或渲染异常
模型发紫通常是 Unity 找不到贴图或者着色器不兼容。排查步骤:
- 检查 FBX 旁边是否有贴图目录,贴图是否被 Unity 正确识别。
- 检查材质使用的着色器是不是 URP/HDRP 不支持的旧式着色器。
- 检查材质映射脚本是否把 CAD 材质名和 Unity 资源名对应上了。
如果贴图文件很多,可以在导入阶段用 AssetPostprocessor 自动调整材质和贴图参数。命名混乱的话,先用材质映射表解决,不要把时间花在手工重置材质上。
6.3 导入卡死、Unity 崩溃或内存不足
出现这种情况,先不要怀疑 realvirtual 本身。大多数原因是模型文件过大或系统资源不足。
处理顺序:
- 查看 Unity 控制台报错和系统内存占用。
- 把大模型拆成多个小模型,逐个导入。
- 检查是否开启了 Read/Write Enabled,大型网格开启后内存占用会明显上升。
- 降低单个 FBX 的面数,或者用简化版本先跑通流程。
如果低配置机器也能导入一个小型模型,不代表它能承受整条产线的批量导入。批量任务前,先估算总模型数量和总面数。一般建议把单个导入任务限制在一个可控范围,比如每批不超过 20 个设备,模型面数总和不超过 300 万,具体数值以你的机器为准。
6.4 最后几点实操建议
踩过几次之后我发现,很多问题不是工具能力不够,而是前置环境和输入材料没有处理干净。这几点建议值得提前记住:
第一,先在源头上规范 CAD 数据。统一单位、坐标、命名、轴心,后面所有环节都会省力。如果源头数据乱,自动化脚本再厉害也救不回来。
第二,小步快跑。第一次测试,哪怕只用一个简单的长方体或一个小零件,也要完整跑通“CAD 转换 → FBX 导入 → realvirtual 装配 → 运动控制”这条链路。链路通顺后再放大模型。
第三,保留脚本和配置表的可重复性。模型更新了,改源文件后重新导出、重跑脚本,而不是在 Unity 场景里手工调整。真正的自动导入,必须做到“源 CAD 更新后,一次脚本跑出新的完整场景”。
第四,性能优化要分阶段。先保证功能可用,再考虑 LOD、碰撞体、场景加载。不要一上来就追求最高性能和最复杂的架构。
realvirtual 的 CAD 自动导入,本质上是一套把“工业模型数据”变成“数字孪生对象”的流水线。流水线的前半段是 CAD 转换和格式处理,后半段是 Unity 导入和 realvirtual 组件配置。把这两段用脚本串起来,配合稳定的命名规范和配置表,大型 CAD 数据的导入速度会有非常明显的提升。真正落地时,最该盯住的不是某个按钮,而是每一步的输入、输出和判断标准是否清晰。