1. 从一张图纸到可交互场景:这条管线到底在解决什么问题
做过机械设计的朋友大概率都经历过这样的场景:在 SolidWorks 里把一套机构画得清清楚楚,装配体干涉检查全绿,工程图也出完了,结果领导或者客户来一句——“能不能做个动画看看它动起来是什么效果?”或者“能不能放到虚拟场景里让我戴着设备走一圈看看?”这时候如果你只会 SolidWorks 自带的运动算例,那基本就只能做个转盘式旋转动画,交互性约等于零。
这条从 SolidWorks 到 Unity 的模型导入管线,解决的就是工业级 CAD 数据向实时交互引擎迁移的问题。SolidWorks 擅长的是参数化精确建模,公差、配合、工程图是它的主场;Unity 擅长的是实时渲染、物理模拟、交互逻辑和跨平台部署。两者之间的数据通道,就是今天要聊透的核心。
适合看这篇内容的人大概分三类:一是机械工程师想把自己的设计做成可交互演示;二是做数字孪生、虚拟仿真的开发者需要接 CAD 数据;三是做工业可视化、VR 培训场景的技术美术,需要处理来自 CAD 的高精度模型。不管你是哪一类,只要涉及“SolidWorks 画完的东西要进 Unity”,这里面的坑你迟早都会踩一遍。
我前后做过十几个从 CAD 到实时引擎的项目,小到单个零件展示,大到整条产线的数字孪生,中间踩过的坑从模型破面到材质全丢、从坐标系错位到性能爆炸,基本把能犯的错都犯了一遍。下面把这些经验系统性地拆开讲,尽量让你少走弯路。
2. 整体思路与方案选型:为什么不能直接拖进去
2.1 两种数据格式的本质差异
SolidWorks 的原生格式是.sldprt(零件)和.sldasm(装配体),这是一种**参数化边界表示(B-Rep)**格式。它记录的不只是模型的形状,还有特征树、草图约束、配合关系、材料属性等一整套设计意图。文件里存的是“这个圆柱是通过拉伸草图X得到的”这样的逻辑。
Unity 能识别的是**多边形网格(Mesh)**格式,常见的有 FBX、OBJ、DAE 等。网格格式只记录顶点坐标、法线、UV 和三角面索引,它不关心这个面是怎么来的,只关心它在空间中的位置。
这就好比 SolidWorks 给的是一份带完整施工工艺的图纸,Unity 只想要一个已经做好的实物模型。中间必须有一个“翻译”过程,把参数化的精确几何转换成三角网格。
2.2 三条主流路线的取舍
目前从 SolidWorks 到 Unity,实际可走的路线主要有三条,各有各的适用场景:
| 路线 | 中间格式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 直接导出 | FBX/OBJ/STL | 操作简单,无需额外软件 | 材质丢失、装配层级可能错乱、大装配体容易出问题 | 单个零件、简单装配体 |
| 中间软件转换 | STEP → 3ds Max/Blender → FBX | 可控性强,能修复破面、重做UV | 多一道工序,需要额外软件技能 | 中等复杂度装配体、需要精细材质 |
| 专业转换工具 | CAD 专用转换器 → FBX | 批量处理能力强,保留层级 | 工具成本高,学习曲线陡 | 大型装配体、产线级场景 |
我个人的建议是:零件数量在 50 个以内、结构不复杂的情况下,直接导出 FBX 就够了;超过这个规模,或者对材质、UV 有精细要求,老老实实走中间软件转换;如果是整条产线几百上千个零件,那就得上专业工具做批量处理和轻量化。
2.3 为什么坐标系和单位是第一个大坑
SolidWorks 默认使用米作为内部单位(虽然界面上你可能设的是毫米),Y 轴朝上。Unity 使用米作为单位,但 Y 轴朝上、Z 轴朝前,左手坐标系。看起来都是米、都是 Y 朝上,应该没问题?实际上问题大了。
SolidWorks 导出 FBX 时,默认会做一个单位缩放。如果你在 SolidWorks 里画了一个 100mm 的方块,导出 FBX 后导入 Unity,可能会发现它变成了 0.1 米或者 100 米,取决于导出设置。更麻烦的是旋转方向,SolidWorks 里绕 Z 轴转 90 度和 Unity 里绕 Z 轴转 90 度,视觉效果可能完全不一样。
实操心得:在 SolidWorks 导出 FBX 的设置面板里,一定要手动确认“单位”选项。我通常的做法是统一设为毫米导出,然后在 Unity 的模型导入设置里把 Scale Factor 设为 0.001,这样 100mm 的零件在 Unity 里就是 0.1 米,符合直觉。
3. SolidWorks 端的导出准备:把问题消灭在源头
3.1 模型清理与简化
在导出之前,有一件事比导出设置本身更重要——清理模型。SolidWorks 装配体里往往包含大量对最终视觉效果毫无贡献但会严重拖累性能的东西:
- 内部看不见的零件(比如装在壳体内的标准件)
- 螺纹特征(在实时渲染里完全可以用贴图代替)
- 倒角和圆角(数量多了三角面数爆炸)
- 装饰性的小特征(logo 凹槽、散热孔阵列等)
我的做法是:另存一个“导出专用”的简化版本,把不影响外观和运动逻辑的细节全部压缩掉。一个典型的工业装配体,简化后三角面数能降到原来的 30% 甚至更低,而视觉效果几乎看不出差别。
具体操作上,可以用 SolidWorks 的“Defeature”功能(在“工具”菜单下),它能自动识别并移除小特征、内部零件和隐藏面。也可以手动压缩不需要的零部件,或者用“配置”功能做一个专门的导出配置。
3.2 装配体层级结构的整理
Unity 里模型的层级结构直接决定了后续做动画和交互的难易程度。如果导出时层级乱七八糟,到了 Unity 里找零件就像大海捞针。
在 SolidWorks 里导出前,建议做这几件事:
- 重命名零部件:把“零件1”“零件2”改成有意义的名字,比如“底座”“传动轴”“滑块”。导出后 Unity 里会保留这些名字。
- 整理装配树:把需要独立运动的零件放在同一层级下,不需要动的可以合并。比如一个机械臂,底座、大臂、小臂、末端执行器应该各自独立,而每个臂上的螺丝、垫片可以合并到父级。
- 检查配合关系:SolidWorks 里的配合关系不会导出到 FBX,但导出时的当前位置会被保留。所以导出前要把装配体调整到一个合理的初始姿态。
3.3 材质与外观的处理策略
SolidWorks 里的材质(比如“不锈钢”“阳极氧化铝”)导出到 FBX 后,Unity 是认不出来的。SolidWorks 的外观信息最多只能导出为基本的颜色信息,而且经常丢失。
我的策略是:在 SolidWorks 里只保留最基本的颜色区分,把材质制作全部放到 Unity 里做。具体来说,给不同材质的零件赋予不同的纯色外观(红、蓝、灰等),导出后在 Unity 里根据颜色或者零件名称来重新赋予 PBR 材质。
这样做的好处是,Unity 的材质系统比 SolidWorks 强大得多,金属度、粗糙度、法线贴图都能精细控制,而且可以实时调整。如果指望从 SolidWorks 直接导出完整材质,大概率会失望。
注意:如果装配体里有透明件(比如玻璃罩、亚克力板),在 SolidWorks 里设置透明度导出后基本都会丢失。建议在 Unity 里单独给这些零件做透明材质,效果更好控制。
4. 导出格式的选择与参数配置
4.1 FBX 导出设置逐项拆解
FBX 是目前从 SolidWorks 到 Unity 最常用的中间格式。在 SolidWorks 里通过“文件 → 另存为 → FBX”可以调出导出设置面板,里面有几个关键选项需要特别注意:
输出类型:选“装配体”还是“零件”?如果是装配体,一定要选“装配体”,否则所有零件会被合并成一个整体,后续没法单独控制。
单位:前面说过了,建议统一用毫米,然后在 Unity 里缩放。也可以直接选米,但要注意 SolidWorks 内部单位换算可能带来的精度问题。
分辨率:这个选项控制的是曲面细分精度。有“粗糙”“中等”“精细”“自定义”几档。我一般选“自定义”,然后把偏差值设为 0.01mm 左右。偏差值越小,曲面越平滑,但三角面数也越多。对于大多数工业零件,0.05mm 的偏差已经足够,再细就是浪费性能。
输出坐标系:SolidWorks 默认是 Y 轴朝上,Unity 也是 Y 轴朝上,但两者的 Z 轴方向相反。导出时可以选择“Y 轴朝上”并勾选“反转 Z 轴”,或者在 Unity 导入时调整旋转。我习惯在导出时就处理好,避免 Unity 里每个模型都要手动转。
导出材质:这个选项建议关掉。前面说了,SolidWorks 的材质导出到 Unity 基本没用,不如在 Unity 里重新做。
导出外观:可以勾选,这样至少能保留基本的颜色信息,方便在 Unity 里按颜色区分零件。
4.2 什么时候该用 STEP 做中转
FBX 直接导出虽然方便,但遇到复杂曲面(比如涡轮叶片、有机形状的壳体)时,经常会出现破面、法线翻转、UV 错乱的问题。这时候 STEP 格式做中转会更可靠。
STEP 是一种中性的 CAD 交换格式,它保留的是精确的 B-Rep 几何,而不是三角网格。把 STEP 导入到 Blender 或 3ds Max 里,这些软件有更强大的网格修复和重拓扑工具,可以手动修复破面、重新计算法线、展 UV,然后再导出为干净的 FBX。
这条路线多了一道工序,但对于曲面复杂、精度要求高的模型,最终效果会好很多。我做过一个叶轮模型的导入,直接 FBX 导出后叶片表面全是黑斑,换成 STEP → Blender → FBX 的路线后,问题完全消失。
4.3 大装配体的分批导出策略
当装配体零件数超过两三百个时,一次性导出 FBX 可能会失败,或者导出的文件巨大无比,Unity 导入时直接卡死。这时候需要分批导出。
具体做法是按功能模块把装配体拆成几个子装配体,分别导出 FBX,然后在 Unity 里用空物体(Empty GameObject)把它们组装起来。比如一条产线可以拆成上料模块、加工模块、下料模块,每个模块单独导出,最后在 Unity 里按实际位置拼合。
这样做还有一个额外好处:Unity 可以对每个模块单独做 LOD(多细节层次),远处的模块用低模,近处的用高模,性能优化空间更大。
5. Unity 端的导入与处理:从网格到可用资产
5.1 模型导入设置详解
FBX 文件拖进 Unity 的 Assets 文件夹后,点击模型文件,Inspector 面板里有一堆导入设置需要调整。这些设置直接决定了模型在场景里的表现,逐项说一下:
Scale Factor:如果 SolidWorks 导出时用的是毫米,这里填 0.001;如果用的是米,填 1。填错了模型要么大得像山,要么小得看不见。
Convert Units:建议勾选,让 Unity 自动处理单位转换。但有时候自动转换会出问题,所以还是要手动确认一下最终尺寸对不对。
Import BlendShapes:如果模型没有变形动画,关掉,省性能。
Import Cameras / Import Lights:SolidWorks 里如果有相机或光源,导出时会带进来,但基本没用,关掉。
Generate Colliders:这个选项要慎重。如果勾了,Unity 会自动给模型生成碰撞体,但 CAD 模型的三角面数通常很高,自动生成的碰撞体又重又不准。建议关掉,后续手动添加简单的碰撞体(Box Collider、Capsule Collider 等)。
Normals:选“Import”或“Calculate”。如果 SolidWorks 导出的法线有问题,选“Calculate”让 Unity 重新算。
Tangents:如果要用法线贴图,必须选“Calculate”。不用法线贴图的话可以关掉,省一点内存。
5.2 材质重建的标准化流程
模型导入后,所有材质都会变成默认的灰色。接下来要做的就是材质重建。我的标准化流程是这样的:
第一步,在 Unity 里创建一个 Materials 文件夹,按零件类型或者材质类型建立子文件夹。比如“金属”“塑料”“橡胶”“玻璃”各一个文件夹。
第二步,创建一个标准材质模板。用 Unity 的 Standard Shader 或者 URP 的 Lit Shader,设置好基本的金属度、粗糙度参数。比如不锈钢:Metallic 设 0.9,Smoothness 设 0.8;阳极氧化铝:Metallic 设 0.8,Smoothness 设 0.5。
第三步,根据零件名称或者颜色批量赋予材质。如果 SolidWorks 导出时保留了颜色信息,可以在 Unity 里按颜色筛选,批量替换。如果没有颜色信息,就只能按名称手动来了。
第四步,给需要细节的零件加法线贴图和 AO 贴图。这一步不是必须的,但对于展示效果要求高的场景,能大幅提升真实感。
实操心得:如果装配体里零件特别多,手动一个个赋材质会疯掉。可以写一个简单的 Editor 脚本,按名称关键词批量赋材质。比如名称里包含“Screw”的全部赋螺丝材质,包含“Bearing”的全部赋轴承材质。这个脚本我用了好几年,至少省了几百个小时的重复劳动。
5.3 层级结构与 Transform 整理
模型导入 Unity 后,层级结构可能和 SolidWorks 里的装配树不完全一致。需要手动整理一下:
- 创建一个空的父物体作为整个模型的根节点,把 Position 归零。
- 把需要独立运动的零件拖出来,放在根节点下,命名清晰。
- 不需要独立运动的零件可以合并到一个父物体下,减少层级深度。
- 检查每个零件的 Transform,确保 Position 和 Rotation 是合理的值。有时候导出导入后会出现极小的偏移或旋转,虽然肉眼看不出来,但做动画时会累积误差。
整理完层级后,建议给根节点挂一个脚本,把所有子物体的初始 Transform 记录下来,方便后续做复位操作。
6. 常见问题与排查技巧实录
6.1 模型破面与法线翻转
这是最常见的问题,表现为模型表面出现黑色斑块、透明区域或者奇怪的阴影。原因通常是三角面法线方向不一致,或者曲面细分时产生了退化三角形。
排查方法:在 Unity 的 Scene 视图里把 Shading Mode 切到“Normals”,法线方向正常的表面会显示为蓝色,翻转的会显示为红色或其他颜色。
解决方法:如果是少量面翻转,可以在 Blender 里手动翻转法线。如果是大面积问题,回到 SolidWorks 检查曲面质量,或者换 STEP 中转路线重新导出。
6.2 材质丢失与 UV 错乱
材质丢失前面说过了,基本无解,只能在 Unity 里重建。UV 错乱的表现是贴图拉伸、重复或者完全对不上位置。CAD 模型通常没有为实时渲染优化过 UV,所以这个问题很普遍。
解决方法:对于简单零件,可以在 Unity 里用 ProBuilder 或者第三方工具重新展 UV。对于复杂零件,建议在 Blender 里用 Smart UV Project 自动展 UV,然后导出 FBX 时带上 UV 信息。
6.3 性能优化:从卡顿到流畅
CAD 模型的面数通常远超实时渲染的需要。一个中等复杂度的装配体,三角面数可能达到几百万甚至上千万,直接扔进 Unity 场景,帧率直接掉到个位数。
优化手段按优先级排列:
| 优化手段 | 效果 | 实施难度 | 适用场景 |
|---|---|---|---|
| 模型简化(Defeature) | 减少 50%-70% 面数 | 低 | 所有场景 |
| LOD 分级 | 远处减少 80% 面数 | 中 | 大型场景 |
| 遮挡剔除 | 减少 30%-50% 渲染量 | 低 | 室内场景 |
| 合并网格 | 减少 Draw Call | 中 | 静态零件多的场景 |
| 贴图代替几何 | 大幅减少面数 | 高 | 螺纹、散热孔等 |
我通常的做法是:先在 SolidWorks 里做一轮 Defeature 简化,然后在 Unity 里对每个模块做 LOD,最后把静态零件合并网格。一套组合拳下来,帧率从 15fps 提到 60fps 是常有的事。
6.4 坐标系错位的快速修复
如果导入后发现模型方向不对(比如躺着的变成了站着的),不要急着在 SolidWorks 里重新导出。在 Unity 里直接调整根节点的 Rotation 就行。常见的情况是 SolidWorks 的 Z 轴朝前,Unity 的 Z 轴也朝前但方向相反,所以根节点绕 Y 轴转 180 度通常能解决大部分问题。
如果模型尺寸不对,调整根节点的 Scale 就行。但要注意,Scale 不是 1 的时候,子物体的 Transform 会受到影响,做动画时容易出问题。所以最好在导入设置里就把 Scale Factor 调对,而不是在场景里缩放。
7. 从静态模型到可交互场景的进阶思路
模型导入只是第一步,真正体现价值的是后续的交互和动画。这里简单提几个方向,给有进一步需求的读者参考。
运动仿真:如果装配体有运动关系(比如齿轮传动、连杆机构),可以在 Unity 里用关节(Joint)组件来模拟。Hinge Joint 做旋转,Configurable Joint 做复杂运动。配合脚本控制,能做出比 SolidWorks 运动算例更灵活的交互。
数字孪生:把模型和实际设备的传感器数据对接,用 Unity 做实时状态展示。比如电机的转速、温度、振动数据,可以驱动模型上的颜色变化、仪表盘指针等。
VR 培训:把模型导入 VR 场景,让操作人员用手柄模拟拆装、维修流程。这种应用对模型的细节要求不高,但对交互逻辑和碰撞检测要求很高。
Web 端展示:Unity 支持导出 WebGL,可以把模型放到网页上让客户直接浏览。但 WebGL 对性能更敏感,模型简化要做得更彻底。
这些方向每一个都能展开讲很多,但核心还是那句话:模型导入的质量决定了后续所有工作的上限。如果导入的模型破面、材质丢失、层级混乱,后面做交互和动画时只会加倍痛苦。所以花时间把导入这一关做好,绝对是值得的。
我个人在实际操作中的体会是,SolidWorks 到 Unity 这条管线,技术难度其实不高,但细节特别多。每一个设置项背后都有它的道理,忽略了任何一个都可能在后面某个环节爆发出来。最省时间的做法不是急着导入看效果,而是先把导出设置、模型简化、层级整理这些准备工作做扎实。前期多花一个小时,后期能省十个小时。