1. 从“37”这个编号说起:Modeling Tools 到底解决了什么痛点
如果你在 UE5 里做过一段时间场景或者道具,大概率经历过这种循环:在 DCC 软件里建好模型,导出 FBX,导入引擎,发现比例不对,切回 DCC 改,再导出,再导入,材质槽又乱了。一个简单的墙面凹槽调整,可能要来回折腾三四次。Modeling Mode 这套工具集的出现,本质上就是把“轻量级模型修改”这件事从外部软件拉回了引擎内部。
标题里的“37”是这套工具集在某个版本迭代中的编号标记,不用太纠结这个数字本身,它更像是一个版本锚点,代表 Modeling Tools 从实验性插件走向正式内置功能的一个阶段。这个阶段最核心的变化有三个:Modeling Mode 工具集正式整合进编辑器模式切换栏、动态网格编辑支持非破坏性工作流、Geometry Script 可以通过蓝图和 Python 驱动程序化建模。
我最初接触这套工具是因为一个室内场景项目,客户要求墙面上的插座孔位要跟电气图纸完全对齐。如果用传统流程,每个孔位都要在 Blender 里定位、布尔、导出,光是重复劳动就让人崩溃。后来改用 Modeling Mode 里的 PolyGroup 编辑加 Geometry Script 批量生成,整个墙面 40 多个孔位,写个脚本 10 分钟跑完,而且后续改参数直接重新跑一遍就行。从那之后我就开始系统性地研究这套工具链。
这篇文章适合三类人看:一是刚接触 UE5 建模、想知道引擎内建模到底能不能替代部分 DCC 工作的新手;二是已经用过 Modeling Mode 但只停留在简单拉伸、倒角层面的中级用户;三是想通过 Geometry Script 做程序化生成、批量处理的技术美术方向从业者。我会从工具集的设计逻辑讲起,然后拆解核心操作细节,再给出一套完整的实操流程,最后把常见坑和排查方法整理出来。
2. Modeling Mode 工具集的设计逻辑与模块拆解
2.1 为什么 UE 要在引擎内做建模工具
这个问题我一开始也没想明白。引擎做好渲染和逻辑就行了,建模交给专业软件不好吗?但实际项目做多了就发现,有一类需求 DCC 软件反而处理起来很别扭。
第一类是环境适配型修改。比如你从素材库买了一个楼梯模型,但你的楼层高度是 3.2 米而不是标准的 3 米,你需要把楼梯拉伸到合适高度,同时踏步数保持不变。这种修改在 DCC 里要重新计算阵列,但在 Modeling Mode 里直接用 Dynamic Mesh 的拉伸加上边循环调整就能搞定。
第二类是程序化批量生成。比如你要在一个城市街区里放置 200 个不同尺寸的窗户,每个窗户的框宽、玻璃分割数都要根据建筑立面自动变化。这种需求用 Geometry Script 写逻辑比手动建模快几个数量级。
第三类是碰撞与视觉的一致性维护。热词里有个“ue5碰撞盒识别不到overlap事件”,这个问题很多时候就是因为视觉网格和碰撞网格是分开制作的,改了视觉网格忘了更新碰撞。Modeling Mode 允许你直接从视觉网格生成简化碰撞,改完即时同步,减少这类低级错误。
注意:Modeling Mode 不是要替代 Maya 或 Blender,它的定位是“引擎内的轻量级修改和程序化生成”。高精度角色建模、复杂曲面造型还是得靠专业 DCC 工具。
2.2 工具集的四大模块划分
Modeling Mode 的工具面板看起来选项很多,但按功能逻辑可以分成四块:
创建与形状模块:包括基础体素(Box、Sphere、Cylinder 等)、多边形绘制、挤出、放样。这块主要解决“从无到有”的问题,适合快速搭建灰模或者占位几何体。
编辑与变形模块:包括 Dynamic Mesh 的推拉、平滑、倒角、桥接、三角面重组。这是日常用得最多的部分,相当于把 Blender 的编辑模式搬进了 UE。
属性与材质模块:包括 UV 展开、材质分配、顶点色绘制、法线调整。这块经常被忽略,但实际上引擎内直接调 UV 比导出到 DCC 再导回来快得多,尤其是只需要简单平面投影的时候。
程序化与脚本模块:Geometry Script 的蓝图节点和 Python API。这是整套工具链里上限最高的部分,也是区分普通用户和技术美术的分水岭。
2.3 动态网格编辑的核心机制
Dynamic Mesh 是 Modeling Mode 的底层数据结构。传统的 Static Mesh 是一旦导入就固定不变的,而 Dynamic Mesh 允许在运行时或编辑时动态修改顶点、边、面。
它的核心优势在于非破坏性迭代。举个例子,你用 Dynamic Mesh 在一个墙面上挖了五个不同大小的洞,后来发现第三个洞的位置偏了 10 厘米。传统流程你要重新布尔运算,但 Dynamic Mesh 会保留操作历史,你只需要调整第三个洞的位置参数,整个网格自动重新计算。
但这里有个坑:Dynamic Mesh 的面数如果太高,编辑操作会明显卡顿。我实测下来,单个 Dynamic Mesh 超过 5 万三角面之后,推拉操作就开始有延迟感。所以建议在编辑阶段用低模,确认形状后再通过细分或者 Nanite 来提升细节。
3. 核心操作细节与实操要点拆解
3.1 进入 Modeling Mode 的正确姿势与初始设置
很多人第一次打开 Modeling Mode 会发现工具是灰的,点不了。这是因为没有选中可编辑的 Actor。正确流程是:
- 在场景中选中一个 Static Mesh Actor
- 点击编辑器左上角的模式切换下拉菜单,选择Modeling
- 此时右侧会出现 Modeling 工具面板,左侧会出现工具分类列表
但这里有个隐藏设置需要提前改。在Editor Preferences > Modeling Mode里,把Asset Creation Mode从默认的“Create New Asset”改成“Overwrite Existing Asset”或者根据你的工作流选择。默认模式下每次操作都会生成一个新的 Static Mesh 资产,做几次修改之后你的内容浏览器里就会多出一堆_Generated后缀的文件,非常乱。
我个人的习惯是:前期探索阶段用“Create New Asset”,确认最终效果后用“Overwrite Existing Asset”覆盖原模型。这样既保留了试错空间,又不会污染资产库。
3.2 Dynamic Mesh 编辑的五个高频操作
第一个是 PolyGroup 编辑。PolyGroup 相当于把网格面分组,你可以按组选择、按组挤出、按组赋材质。在 Modeling Mode 里按Shift+G可以快速进入 PolyGroup 编辑模式。这个功能在做硬表面模型时特别好用,比如一个机械零件的不同功能区域可以用不同 PolyGroup 区分,后续调整时直接选组操作。
第二个是三角面与四边面转换。UE 的 Dynamic Mesh 默认是三角面,但编辑时四边面更直观。在工具面板里找到Tri to Quad和Quad to Tri可以互相转换。我的经验是:推拉变形用四边面,最终输出前转回三角面,因为 UE 渲染管线对三角面优化更好。
第三个是边循环插入。在需要增加细节的地方,用Insert Edge Loop工具在指定位置插入一圈边。操作方式是按住Ctrl点击边,然后拖动到目标位置。这里有个技巧:插入边循环时按住Shift可以吸附到网格的 25%、50%、75% 位置,做对称结构时非常方便。
第四个是桥接。两个分离的开口之间可以用Bridge工具连接。选中两个边缘循环,点击 Bridge,引擎会自动生成连接面。这个功能做管道、走廊连接处特别快。
第五个是投影与吸附。Project工具可以把一个网格的顶点投影到另一个网格表面。做贴合地面的石块或者墙面装饰时,用这个工具比手动调整顶点快得多。
3.3 Geometry Script 的接入方式与执行环境
Geometry Script 有两种使用方式:蓝图和 Python。
蓝图方式适合做交互式工具。在 Content Browser 里右键创建Editor Utility Blueprint,然后在蓝图里调用 Geometry Script 节点。比如你可以做一个“批量倒角”工具,选中多个 Actor 后一键给所有边缘加倒角。
Python 方式适合做批处理和自动化。UE5 内置了 Python 编辑器,在Output Log里把输入模式切换到 Python 就可以直接执行脚本。我常用的一个脚本是批量修改选中 Actor 的网格分辨率:
import unreal selected_actors = unreal.EditorLevelLibrary.get_selected_level_actors() for actor in selected_actors: mesh_component = actor.get_component_by_class(unreal.StaticMeshComponent) if mesh_component: static_mesh = mesh_component.get_editor_property("static_mesh") # 这里调用 Geometry Script 的简化函数 unreal.GeometryScriptLibrary.set_mesh_simplify(static_mesh, 0.5)这段代码的意思是:获取当前选中的所有 Actor,找到它们的 StaticMeshComponent,然后把网格简化到 50% 的面数。做 LOD 或者性能优化时非常实用。
提示:Geometry Script 的 Python API 在 UE5.1 之后才比较稳定,如果你用的是早期版本,部分函数可能不存在或者参数不同。建议至少用 UE5.2 以上版本。
3.4 UV 与材质在引擎内处理的取舍
Modeling Mode 内置了 UV 展开工具,包括平面投影、柱面投影、盒式投影。我的建议是:简单几何体在引擎内做 UV,复杂曲面还是回 DCC。
原因很简单,引擎内的 UV 展开算法精度有限,做建筑墙面、地板、简单道具没问题,但做角色面部或者有机曲面时,接缝和拉伸问题会比较明显。我试过用引擎内工具给一个雕塑模型展 UV,结果接缝处出现了明显的纹理错位,最后还是回 Blender 用 Smart UV Project 重新做的。
但有一个场景引擎内 UV 特别有优势:程序化生成的几何体。比如你用 Geometry Script 生成了 100 个不同尺寸的窗户,每个窗户的 UV 都需要根据尺寸自动调整。这时候用脚本批量做平面投影,比手动一个个展 UV 快无数倍。
4. 完整实操流程:从零搭建一面带孔洞的程序化墙面
4.1 需求分析与参数规划
假设我们要做一面 4 米宽、3 米高的墙面,上面有 6 个插座孔,孔的位置和大小由外部数据决定。后续可能还要调整孔的数量和位置,所以整个流程要参数化。
参数规划如下:
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| WallWidth | Float | 400 | 墙面宽度(厘米) |
| WallHeight | Float | 300 | 墙面高度(厘米) |
| WallThickness | Float | 20 | 墙面厚度(厘米) |
| HoleRadius | Float | 5 | 孔洞半径(厘米) |
| HolePositions | Vector Array | 6个坐标 | 孔洞中心位置 |
4.2 第一步:创建基础墙面网格
在 Modeling Mode 里创建一个 Box,尺寸设置为 400 x 20 x 300。然后进入Dynamic Mesh编辑模式,用Insert Edge Loop在墙面正面插入几圈边,目的是增加网格密度,方便后续布尔运算时孔洞边缘更平滑。
这里有个经验值:孔洞边缘的平滑度取决于孔洞周围的面数。如果墙面只有 6 个面,布尔出来的孔洞会是六边形而不是圆形。我一般会在孔洞预期位置周围插入 3 到 4 圈边,保证布尔后孔洞边缘至少有 12 到 16 个顶点。
4.3 第二步:用 Geometry Script 批量生成孔洞
手动一个个挖孔太慢,我们用 Geometry Script 写一个循环。在 Editor Utility Blueprint 里创建一个函数,输入墙面 Mesh 和孔洞位置数组,输出挖好孔的 Mesh。
核心逻辑是:遍历 HolePositions 数组,在每个位置创建一个圆柱体,然后用Apply Mesh Boolean节点从墙面网格中减去圆柱体。布尔运算的模式选择Difference。
这里有个性能优化的点:不要每次布尔都生成一个新的 Dynamic Mesh,而是把所有圆柱体先合并成一个“孔洞集合网格”,然后用一次布尔运算减去这个集合。这样比循环 6 次布尔快大约 3 到 4 倍。
4.4 第三步:孔洞边缘的倒角与平滑处理
布尔运算出来的孔洞边缘是直角硬边,视觉上不够真实。用Bevel工具给孔洞边缘加一个 0.5 厘米的倒角。操作时选中孔洞边缘的边循环,点击 Bevel,设置距离为 0.5,段数为 2。
然后切换到Smooth工具,对倒角区域做一次轻度平滑,强度设为 0.3 左右。这样孔洞边缘会有轻微的高光过渡,看起来更像真实开孔。
4.5 第四步:UV 展开与材质分配
墙面主体用盒式投影展 UV,孔洞内壁用柱面投影。在 Modeling Mode 的UV Editor里可以分别选中不同 PolyGroup 做不同的投影方式。
材质分配上,墙面主体给一个乳胶漆材质,孔洞内壁给一个深色塑料材质。这里可以用PolyGroup 材质分配功能,按组赋材质,比手动选面快得多。
4.6 第五步:碰撞生成与 Overlap 事件测试
墙面需要碰撞,否则角色会穿模。在 Modeling Mode 里用Generate Collision工具,选择Convex Decomposition模式。这个模式会把网格分解成多个凸包,适合带孔洞的复杂形状。
生成碰撞后,在蓝图里给墙面添加一个 Box Collision 组件,设置碰撞预设为OverlapAllDynamic。然后写一个简单的测试蓝图:角色靠近墙面时触发 Overlap 事件,打印一条日志。
这里就涉及到热词里提到的“ue5碰撞盒识别不到overlap事件”问题。常见原因有三个:一是碰撞预设设置成了 Block 而不是 Overlap;二是碰撞体没有正确生成,比如 Convex Decomposition 失败导致碰撞体为空;三是 Overlap 事件绑定在了错误的组件上。排查方法后面会详细讲。
5. 常见问题与排查技巧实录
5.1 碰撞盒识别不到 Overlap 事件的排查思路
这个问题我在项目里遇到过至少三次,每次原因都不一样。整理一个排查顺序:
第一步:检查碰撞预设。在 Static Mesh 编辑器的 Collision 面板里,确认 Collision Presets 设置的是 Overlap 而不是 Block。如果预设是 BlockAll,Overlap 事件不会触发。
第二步:检查碰撞体是否存在。在编辑器里按Alt+C可以可视化碰撞体。如果看不到任何碰撞线框,说明碰撞体没有生成。回到 Modeling Mode 重新生成一次,或者手动添加简单碰撞。
第三步:检查 Overlap 事件的绑定对象。在蓝图里,Overlap 事件是绑定在 Collision Component 上的,不是绑定在 Actor 上的。如果你把事件绑定到了 Actor 的根组件,而根组件没有碰撞,事件就不会触发。
第四步:检查碰撞通道。在 Project Settings > Collision 里确认两个物体的碰撞通道是否互相响应。比如一个物体是 WorldStatic,另一个是 Pawn,如果 WorldStatic 的碰撞响应里 Pawn 被设置为 Ignore,Overlap 也不会触发。
5.2 Dynamic Mesh 编辑卡顿的优化方案
前面提到过,面数超过 5 万之后编辑会卡。除了降低面数,还有几个优化手段:
- 关闭实时预览:在 Modeling Mode 面板里把Live Preview关掉,操作完再手动应用
- 使用LOD编辑:在低 LOD 上做形状调整,高 LOD 只做细节
- 分块编辑:把大网格拆成几个小网格分别编辑,最后合并
- 升级硬件:Dynamic Mesh 编辑主要吃单核 CPU 性能,高频 CPU 比多核更有优势
5.3 Geometry Script 执行失败的常见原因
Geometry Script 的报错信息有时候很模糊,我整理了几个高频错误:
| 错误现象 | 可能原因 | 解决方法 |
|---|---|---|
| 节点执行后网格为空 | 输入网格的 Dynamic Mesh 没有正确初始化 | 检查输入是否为空,加一个 Is Valid 判断 |
| 布尔运算结果异常 | 两个网格没有相交或者法线方向相反 | 确认网格有重叠区域,检查法线朝向 |
| Python 脚本报 AttributeError | API 版本不匹配 | 查官方文档确认当前 UE 版本的函数名 |
| 批量处理时崩溃 | 内存溢出 | 分批处理,每处理 50 个对象后手动清理一次 |
5.4 引擎内建模的边界与取舍经验
用了两年多 Modeling Mode,我的体会是:它适合做“修改”和“生成”,不适合做“创作”。
修改方面,比如调整比例、挖孔、倒角、简化、UV 重投影,这些引擎内做比 DCC 快。生成方面,比如程序化摆放、批量布尔、参数化构件,Geometry Script 的优势非常明显。
但创作方面,比如角色雕刻、复杂硬表面设计、有机曲面造型,还是得用专业工具。我试过在引擎内做一个机械臂的复杂关节,做到一半就放弃了,因为推拉工具在复杂拓扑上的精度和效率远不如 Blender 的编辑模式。
所以我的工作流是:DCC 做主体创作,引擎内做适配修改和程序化生成。两者配合,而不是互相替代。
6. 进阶方向:Geometry Script 与蓝图工具链的联动
6.1 用 Editor Utility Widget 做自定义建模面板
如果你经常做某类重复性建模操作,可以做一个自定义的 Editor Utility Widget。比如我们项目里经常需要给建筑墙面加窗户,我就做了一个面板:输入楼层高度、窗户间距、窗户尺寸,点击生成,自动在墙面上排列窗户并挖孔。
实现方式是:Editor Utility Widget 里放几个 Slider 和 Button,Button 的 OnClicked 事件里调用 Geometry Script 的函数。这样即使不懂蓝图的美术同学也能一键生成,大大减少了沟通成本。
6.2 与 PCG 工具集的配合思路
UE5 的 PCG(Procedural Content Generation)框架和 Geometry Script 是互补的。PCG 负责“在哪里放”,Geometry Script 负责“放什么”。
比如你要在一片区域里随机散布石块,PCG 可以生成散布点,然后每个点调用 Geometry Script 生成一个随机形状的石块。这样每次运行都能得到不同的结果,而且所有石块都是真实几何体,不是贴图假象。
6.3 性能考量与资产规范
程序化生成的资产如果不加控制,很容易面数爆炸。我的建议是:
- 生成的网格面数控制在 5000 三角面以内
- 及时生成 LOD,可以用 Geometry Script 的 Simplify 函数自动生成
- 碰撞体用简单形状,不要用复杂网格
- 生成的资产命名要有规律,方便后续批量管理
提示:Geometry Script 生成的资产默认保存在内存里,记得用Save Asset节点持久化到磁盘,否则编辑器重启后就丢了。
7. 我个人在实际操作中的几点体会
这套工具链我用了两年多,踩过的坑和总结的经验大概能写一本书,这里挑几个最有价值的说。
第一个体会是:不要试图用 Modeling Mode 做所有事。我刚开始的时候很兴奋,觉得终于可以告别 DCC 了,结果做了一个复杂的机械零件,花了 6 个小时,最后效果还不如在 Blender 里 1 个小时做的。工具是有边界的,认清边界才能高效工作。
第二个体会是:Geometry Script 的学习曲线在“理解数据结构”上,不在“写代码”上。很多人觉得要学 Python 或者蓝图很麻烦,但实际上 Geometry Script 的节点就那么几十个,真正难的是理解 Dynamic Mesh 的顶点、边、面、PolyGroup 之间的关系。理解了数据结构,写逻辑就是顺理成章的事。
第三个体会是:版本更新会带来 API 变化。UE5 从 5.0 到 5.4,Geometry Script 的函数名和参数改了好几次。如果你在网上找到的教程代码跑不通,先查一下版本兼容性,不要怀疑自己的环境有问题。
最后分享一个小技巧:在 Modeling Mode 里按F可以聚焦到当前选中的网格,按Alt+鼠标左键可以旋转视角,按Alt+鼠标中键可以平移。这些快捷键和 Blender 的操作逻辑很像,如果你有 Blender 基础,上手会非常快。另外,Modeling Mode 的所有操作都支持Ctrl+Z撤销,不用担心改坏了回不去,大胆试就行。