Hi3D 1.0 生成的模型能直接进 Unity 吗——还是得先重拓扑?

文章导读
Hi3D 1.0 这类图生模工具产出的网格,能不能直接拖进 Unity,通常不看它是谁生成的,而看你要拿这个模型做什么。静置在场景里当摆件的道具,多数情况下清理一下尺寸和材质就能直接用;一旦要挂 Animator、要做碰撞、要生成 LOD,或者要绑骨骼做动画,网格本身就得先处理——轻则减面,重则重拓扑。判断顺序建议是:先量尺寸,再数三角面,再看材质贴图,最后按用途定去留。
📋 目录
  1. 一 先量尺寸:在 Blender 里核对单位与轴向
  2. 二 统计三角化后的面数
  3. 三 处理材质与贴图路径
  4. 四 判断用途:静置道具、可交互物件、要绑定的部件
  5. 五 写一段导入后自动检查的脚本骨架
A A

Hi3D 1.0 这类图生模工具产出的网格,能不能直接拖进 Unity,通常不看它是谁生成的,而看你要拿这个模型做什么。静置在场景里当摆件的道具,多数情况下清理一下尺寸和材质就能直接用;一旦要挂 Animator、要做碰撞、要生成 LOD,或者要绑骨骼做动画,网格本身就得先处理——轻则减面,重则重拓扑。判断顺序建议是:先量尺寸,再数三角面,再看材质贴图,最后按用途定去留。

先按用途分流:静置道具可直接进 Unity,导入前只需核对单位、轴向和贴图;需要碰撞、LOD 或大量实例的物件,通常要先减面并准备简化碰撞体;需要绑骨骼做形变的部件,一般绕不开重拓扑,因为生成网格的边流通常不适合权重分配。所有判断都可以在 Blender 的统计面板和 Unity 的导入预览里逐项验证,不依赖任何效果承诺。

先量尺寸:在 Blender 里核对单位与轴向

导入后比例失调或者模型躺倒,是这类生成资产最常见的两个导入问题,而且都能在导入前查出来。在 Blender 里打开右侧 N 面板的 Item 页,读 Dimensions 的三个数值,再按以下步骤比对:

  1. 场景属性里确认 Unit System 为 Metric、Unit Scale 为 1.0、Length 为 Meters,这是后续所有尺寸判断的基准。
  2. 加一个默认立方体(尺寸 2m)或一个已知高度的角色替身放在模型旁边,目视对比模型是否整体偏大或偏小一个数量级。
  3. 看模型的上方向:如果模型的“头顶”朝向 +Y 而不是 +Z,说明导出时轴向需要调整。导出 FBX 时在 Export 面板把 Forward 设为 -Z、Up 设为 Y,与 Unity 的坐标习惯对齐。

进入 Unity 后的验证方式是:把模型拖进场景,和 Unity 自带的 Cube(1×1×1)并排,检查 Transform 的 Scale 是否仍为 1、模型包围盒是否符合预期高度;如果 Scale 被自动改成了 0.01 或 100 之类,基本可以判定导出单位是厘米或需要重新导出,而不是靠手动改 Scale 掩盖。

统计三角化后的面数

Unity 渲染时只认三角面,而 Blender 里看到的 Faces 多数是四边面,直接读 Faces 会低估实际开销。在 Blender 中按 Shift+Alt+Z 打开 Overlays 的 Statistics,视口左上角会同时显示 Faces 和 Tris,以 Tris 为准;也可以全选后在编辑模式执行 Ctrl+T 三角化,再看状态栏的面数,得到一个确定的三角面值。

Unity 侧的对照方法是:在 Project 窗口选中模型资产,Inspector 顶部的预览小窗下方会列出 Vertices 和 Triangles;点开 Model 选项卡同样能看到。注意两边的顶点数通常对不上,这是正常的——Unity 会按 UV 缝和法线拆分拆开顶点,顶点数往往比 Blender 多,但 Triangles 数应当接近。如果 Triangle 数差异很大,先看是不是把多个子网格一起导入了,或者模型里藏着没注意的隐藏物体。

Hi3D 1.0 生成的模型能直接进 Unity 吗——还是得先重拓扑?

处理材质与贴图路径

生成模型导出时,贴图可能是内嵌在文件里,也可能是同目录的独立图片,两种方式进 Unity 后行为不同。导入后先这样查:选中模型资产,在 Inspector 的 Materials 选项卡里看有几个材质槽;再把模型拖进场景,选中渲染体,看材质球的 Albedo、Normal 等贴图槽是否为空白或显示 “None”。槽位为空,就是贴图没有随文件带入,需要手动指定。

  • 手动指定:把贴图文件放到 Assets 下一个固定的贴图目录(例如 Assets/Models/Tex),再把图片拖到材质球对应槽位;模型自带的材质建议先 Extract Materials 抽成独立材质球再改,避免改动被下次重新导入覆盖。
  • 法线贴图需要单独把 Texture Type 设为 Normal map,否则凹凸方向会不对。
  • 如果贴图数量多,可以写一个小的编辑器脚本按命名规则批量回填,但第一次仍建议手动接一个样本确认槽位和命名对得上。

判断用途:静置道具、可交互物件、要绑定的部件

这是决定要不要重拓扑的分界线,三类用途的判定条件和验证方式不一样:

  • 静置道具:可以直接用。条件是尺寸对、三角面数在项目预算内、法线朝向正确没有反面。验证方式是在 Scene 视图里绕着看一圈,把材质临时换成双面或 Unlit 对比,确认没有黑洞和翻面;再看阴影投出来是否连续。
  • 可交互物件:通常需要减面和简化碰撞。判定依据是它会不会被大量复制、会不会每帧被射线检测命中。验证方式是把 MeshCollider 换成 BoxCollider 或凸包碰撞,观察交互是否仍然够用;面数明显高于同场景其他道具时,先减面再谈优化。
  • 要绑定的部件:一般必须重拓扑。生成网格多为密集三角面,缺少沿关节走向的均匀边流,自动权重容易在肘、膝、肩处拉扯穿插。验证方式是在 Blender 里给一段简单的两骨链条做自动权重,摆到极限角度看形变是否塌陷;如果塌陷明显,重拓扑比反复修权重更省事。

写一段导入后自动检查的脚本骨架

尺寸和面数这类问题,靠人肉复查容易漏。可以用 AssetPostprocessor 在模型导入完成时读一次网格数据,超过阈值就打印警告。脚本放在 Assets/Editor 目录下,例如 ModelImportChecker.cs,只在编辑器里生效,不会打进运行包。

using UnityEditor;
using UnityEngine;

public class ModelImportChecker : AssetPostprocessor
{
    // 按项目预算调整,这里只是示例阈值
    const int VertexWarnThreshold = 30000;
    const float MaxSizeMeters = 5f;

    void OnPostprocessModel(GameObject go)
    {
        if (!assetPath.EndsWith(".fbx") && !assetPath.EndsWith(".obj")) return;

        foreach (var mf in go.GetComponentsInChildren<MeshFilter>(true))
        {
            var mesh = mf.sharedMesh;
            if (mesh == null) continue;

            if (mesh.vertexCount > VertexWarnThreshold)
            {
                Debug.LogWarning($"[ModelCheck] {assetPath} / {mf.name} 顶点数 {mesh.vertexCount} 超过阈值 {VertexWarnThreshold},考虑减面或重拓扑。");
            }

            Vector3 size = mesh.bounds.size;
            if (size.x > MaxSizeMeters || size.y > MaxSizeMeters || size.z > MaxSizeMeters)
            {
                Debug.LogWarning($"[ModelCheck] {assetPath} / {mf.name} 包围盒 {size} 偏大,先确认导出单位是否为米。");
            }
        }
    }
}

验证方式是:把脚本保存后回到 Unity,在 Project 窗口右键目标模型选 Reimport,或直接重新拖入一次文件,Console 里应出现对应的黄色警告;把阈值临时改小(例如改成 100)再 Reimport,警告应当稳定触发,说明脚本已经生效。要注意的是,如果你在导入设置里关闭了 Read/Write Enabled,读取 mesh.triangles 这类数据可能受限,脚本骨架里只用 vertexCount 和 bounds 判断就是为了避开这个限制;需要精确三角面数时,再单独打开 Read/Write 并在 Console 里确认数值与 Inspector 预览一致。