MENU

• 2025 年 10 月 24 日 • 已有 38 只咪围观过 • -学海拾贝-

插件适配条件:daz资产导出,或者命名/路径温和资产
UE 版本参考:UE5.2–5.4(需启用 Editor Scripting UtilitiesPython Editor Script Plugin
在慢慢迁移csdn的文章,让语言和逻辑更严谨>w<

前言

魔兽的家园系统要上线了,我想要自己先行做一个自己的cg。
我的预想是在一个酒馆类似的场景(魔兽的旅馆都很像酒吧hhh)和我的猫在迎接朋友,但是我找了很多ue资产感觉不满足我的精度需求,于是我找了一套影视级的场景。

好消息是网格和材质齐全;
坏消息是材质只有一个 BaseColor,贴图与材质命名混乱,其他通道(Roughness、Metallic、Normal 等)虽然已导入,但没被正确引用。

现状:

  • 静态网格体
    .../Content/Maps/StaMesh/1_WoodenCup_dup_2_Shape.uasset
  • 材质球
    .../Content/Maps/StaMesh/metal_dark_ncl1_2.uasset
  • 材质槽名
    slotname: metal_dark_ncl1_2
  • 关联的基础色贴图
    .../Libs/Content/Maps/StaMesh/WoodenCup_PNTR_Mat1_BaseColor_M.uasset

换句话说,同一处逻辑上有三个不同的“名字”。同时,我已把需要的贴图都导入到:

  • .../Content/Maps/Textures/

目标:把所有静态网格体的材质,批量替换为规范的 PBR(以统一的母材质 pbr_base 为父项),并正确绑定各通道贴图

ST00007_1.jpeg


设计目标与约束

目标

  1. 批量遍历 StaMesh 路径下所有 Static Mesh
  2. 对每个网格,读取当前材质 → 找到或推断其 BaseColor 贴图 → 由其命名推导出其它通道;
  3. 基于统一母材质 pbr_base 创建 材质实例(MIC),参数名规范:

    • BaseColorTexture
    • NormalTexture
    • RoughnessTexture
    • MetallicTexture
  4. 新实例命名与原材质同名(或同名+后缀),统一存入:
    Z:/Yumi/UEpro/Libs/Content/Maps/Mats/
  5. 将新材质实例回写到对应 Static Mesh 的材质槽。

约束与前提

  • 内容浏览器路径与磁盘路径映射:
    通常 .../Content/... 对应 UE 虚拟路径 /Game/...
    示例:
    .../Content/Maps/StaMesh/.../Game/Maps/StaMesh/...
  • 已有统一母材质 /Game/Maps/Mats/pbr_base(或按你项目的实际路径);内部暴露了上述 4 个 Texture 参数名
  • 命名规则:

    • 基准名:{name} = 去掉 _BaseColor* 后缀前的部分
    • 将在 /Game/Maps/Textures/ 下尝试这些候选:

      • {name}_BaseColor
      • {name}_Normal_OGL(注意 OGL/DirectX 差异,后文说明)
      • {name}_Roughness
      • {name}_Metallic
  • 对于非标资产有提示以及可操作空间

ST00007_2.jpeg


总体流程

Step 0|准备与校验

  • 确保启用插件:Editor Scripting UtilitiesPython Editor Script Plugin
  • 统一 UE 虚拟路径常量:

    • MESH_ROOT = "/Game/Maps/StaMesh"
    • TEX_ROOT = "/Game/Maps/Textures"
    • MAT_ROOT = "/Game/Maps/Mats"
    • PBR_PARENT = "/Game/Maps/Mats/pbr_base"

Step 1|遍历 Static Mesh 并收集材质引用

  • 通过 Asset Registry 获取 MESH_ROOT 下所有 StaticMesh
  • 逐个读取其 材质槽StaticMaterials),得到 MaterialInterface

    为了避免搞乱实际文件,我复制了一个测试文件,这一步通过log验证成功。

ST00007_3.jpg

Step 2|确定 BaseColor 贴图与“基准名”

  • 若材质是 Material Instance:尝试直接读取 BaseColorTexture 参数;
  • 若是 Material(有节点图):用 MaterialEditingLibrary.get_used_textures 获取用到的贴图,从中筛选 _BaseColor
  • 解析 基准名 {name}:截取 _BaseColor 之前的部分(保留中间体如 WoodenCup_PNTR_Mat1)。

    这时候初见端倪,说明有不规范文件

ST00007_4.jpeg

Step 3|按命名规则拼出其它通道并匹配资产

  • TEX_ROOT 下查找同名贴图(不存在则降级匹配:模糊包含 Normal/Rough/Metal 的同前缀资源);
  • 记录缺失项(例如缺 Metallic 时,可默认 0 或走 ORM/MRA 通道扩展,见扩展章节)。

    字符串拼接教程

ST00007_5.jpeg

Step 4|创建材质实例(MIC)

  • 使用 AssetToolsSubsystemMaterialInstanceConstantFactoryNew,设定父项为 pbr_base
  • 新实例命名:与原材质同名(避免替换逻辑混乱),或使用 {OriginalMatName}_PBR 后缀;
  • 目标目录:MAT_ROOT
实践中卡住的关键点之一是忘记 Get Asset Tools(之前编写的函数包,非官方内置),导致无法正确创建资产。这里必须显式:unreal.AssetToolsHelpers.get_asset_tools()get_editor_subsystem(AssetToolsSubsystem)。单独开了一个窗口疯狂测试。用其他方式也可以,主要是需要强刷编辑器状态..

ST00007_6.jpeg

Step 5|写入参数

  • Material Editing Library

    • set_material_instance_texture_parameter_value(MIC, "BaseColorTexture", BaseColorTex)
    • ... "NormalTexture", "RoughnessTexture", "MetallicTexture"
  • 注意:如果函数返回 False,通常是参数名不匹配类型不对。也可能是编辑器状态未刷新。但是实际上时已经设置好的。(step4卡住的原因)。

    这里step4还没解决,第二天问大佬才解决的,第一天晚上先把能走的流程走一次,所以我是假设我已经完成了step4,继续往后推。我喜欢先全走一次踩坑,再突破卡点。

ST00007_7.jpeg

Step 6|回写到 Static Mesh

  • StaticMeshEditorSubsystemset_material(StaticMesh, SlotIndex, MIC) 替换材质;
  • 保存:EditorAssetLibrary.save_loaded_asset(保存 静态网格新建材质实例 两者)。

ST00007_8.jpg

Step 7|一致性与排查

  • 日志输出:对每个网格打印命中的贴图、创建的实例、替换的槽;
  • 失败重试策略:缺贴图 → 留空或默认值;已存在实例 → 直接载入并覆盖参数;
  • 最终导出一份 报告(多少个网格成功、缺失哪些贴图、哪些材质实例已跳过等)。

演示


EUW(Editor Utility Widget)蓝图实现要点

核心节点与顺序如下:

  1. Get Asset RegistryGet Assets by Path (Recursive) → 过滤 StaticMesh
  2. ForEach StaticMesh:

    • Get Static Materials → ForEach Slot → MaterialInterface
    • 取 BaseColor 贴图:

      • Material Editing Library / Get Used TexturesFilter 名含 _BaseColor
      • Regex/Substring 提取 {name}
  3. Get Asset Tools(卡住的点)

    • MaterialInstanceConstantFactoryNew(Set Initial Parent = pbr_base
    • Create Asset(Name = 原材质名,Path = MAT_ROOT
  4. Material Editing Library

    • Set Material Instance Texture Parameter Value ×4(参数名与母材质一致)
    • Save Asset(MIC)
  5. StaticMeshEditorSubsystem

    • Set Material(StaticMesh, SlotIndex, NewMIC)
    • Save Asset(StaticMesh)

提示

  • Set Material Instance Texture Parameter Value 返回 false优先检查参数名是否与 pbr_base 完全一致;
  • 若蓝图中表现为必须“关了再开”才生效,多半是未保存编辑器缓存没刷新:在每次设置后调用 Save Asset,必要时补一个 Post Edit Change 节点(或在 Python 里调用)。

常见坑与解决策略

  1. Get Asset Tools → 无法创建资产

    • ✅ 在 EUW 中显式调用 Get Asset Tools刷新
  2. 参数设置返回 false,但视觉上生效/或需要重启

    • ✅ 对齐 参数名
    • ✅ 设置后 Save Asset + Post Edit Change;必要时 update_material_instance / recompile_material
  3. OGL 法线进 UE 导致高光/凹凸反了

    • ✅ 统一在贴图资产上打勾 Flip Green Channel;或在母材质中处理。
  4. 贴图缺失

    • ✅ 允许降级:缺 Metallic → 0,缺 Roughness → 0.5(或走常量且暴露标量参数);
    • ✅ 支持模糊匹配,如 {name}_R{name}_M、包含 Rough/Metal 的变体。
  5. 批量回写导致资源“脏”且未保存

    • ✅ 每创建/修改一个资产后立即 save_loaded_asset
    • ✅ 整批结束后再保存一次整个目录(

可能的扩展与优化(如果我要迭代)

  • 命名字典表:如果第三方包的命名更混乱,可建立 {alias → 标准名} 的映射表,或用正则/Levenshtein 做模糊匹配,提高命中率。
  • 金属/粗糙合并贴图支持(MRA/ORM):若发现只有一张合并图,可在母材质里拆通道(B=Metallic, G=Roughness, R=AO 等),脚本只需设置一张 Texture 参数。
  • 日志与报表:将每个网格的处理结果写入 CSV(资产名、槽位、命中的贴图、缺失项、是否新建实例),便于复核。
  • 干跑(Dry-Run)模式:先打印将要替换的内容,不真正落盘,减少风险。
  • 断点续跑:已存在同名实例时直接载入并“覆盖参数”,避免重复创建。
返回文章列表 打赏
本页链接的二维码
打赏二维码