从3D模型渲染物品图标
将游戏自身的预制体通过代码转换为一致的图标精灵:一个独立的预览场景、正交相机、三盏方向光、每个模型自动选择的摆位、2×超采样渲染、预乘降采样以及一个深色轮廓,确保图标在任何背景下都清晰可读。可重复运行——当美术资源或物品形状变化时可重新生成。
工作流程
- 检查渲染管线。 模板目标是 URP(
UniversalAdditionalCameraData)。如果是内置渲染管线,删除该代码块;如果是 HDRP,使用HDAdditionalCameraData并以相同方式禁用后期处理。 - 复制
templates/Editor/ModelIconRenderer.cs到一个仅编辑器文件夹/程序集定义文件中(如果使用程序集定义,需引用 URP 运行时库),并重命名命名空间。 - 确定映射关系:从游戏数据到渲染任务——每个物品对应的预制体、其网格占用(普通图标为 1×1;网格背包为物品的网格形状)以及输出路径。将该映射关系保存在项目的内容代码中,而非渲染器中。
- 从菜单项或内容构建步骤调用
ModelIconRenderer.RenderBatch(jobs),然后将生成的精灵赋值给物品数据(AssetDatabase.LoadAssetAtPath<Sprite>(path)),调用SetDirty和SaveAssets。PNG 文件作为精灵导入(透明度为透明通道,无 mipmap)。 - 使用
scripts/icon_sheet.py查看每个图标,并根据每个物品的具体问题修复异常值(参见审查循环),而不是调整全局启发式参数。 - 通过 Git LFS 提交 PNG 文件。 不要将有版权美术资源的图标提交到公共仓库。
摆位选择方式
- 细长模型(最长轴 > 中间轴 1.6 倍:剑、法杖、箭、魔杖)沿着槽的长轴放置——高槽中垂直,宽槽中水平,方形槽中斜放——然后绕该轴旋转 25°,使侧面朝向相机。
- 紧凑模型(宝石、药水、书籍、宝箱)从直立 3/4 视角开始,然后扫描偏航角(−90…90)、俯仰角(−50, −25, 0)和翻滚角(0…135),渲染一个小探针并保留轮廓像素最多的视角。使用像素覆盖而非包围盒可以避免细长对角线胜出;正对视角会被惩罚 7%(因为显得扁平);自动摆位获得 10% 的加分,只有在明显更好的视角才会被替代。
- 紧凑模型放在长槽中(覆盖 < 30%,槽比例 ≥ 3:1):会将副本沿槽平铺,并带有轻微的旋转/缩放变化(例如在 1×3 的槽中放三个碎片),而不是放入一个很小的模型。
- 朝向: 大多数资源包(包括 Synty)的预制体朝向 +Z 方向;相机沿 +Z 方向观察,因此模型首先进行 180° 偏航旋转(
Options.facingCorrection)。如果资源包朝向不同,请修改此值。
审查循环
永远不要信任未经审查的批处理结果。一张缩略图联系表能发现上百行日志发现不了的问题。
- 生成联系表:
python scripts/icon_sheet.py <图标文件夹> sheet.png --match ^Armor_ Shield --strip-prefix,然后查看图像。图标保持其宽高比,因此 3×1 的物品会显示为一条带状,如同在网格中一样。 - 对每个不好的图标分类——修复方法不同:
- 侧对 / 躺倒 / 背对相机 → 使用
rotationOverride设置摆位。它将作为Euler(override) * facingCorrection应用,因此类似(0,0,0)的值表示“按作者原样,面向相机”:细微的倾斜如(-5, 15, 0)给出一个直立的 3/4 视角。(0, 180, 0)显示背面。零值表示“自动”,因此如果要精确使用作者原始摆位,请使用一个微小的非零值。 - 边缘看过去的扁平物体(盾牌、盘子、硬币) → 预制体通常有一个旋转的子物体(武器显示预制体通常将网格绕 X 轴旋转 90° 以便在游戏中平放)。在猜测前先记录子物体的
localEulerAngles;在 override 中抵消该旋转并添加一个翻滚角,使长边沿槽方向放置,例如扁平椭圆形盾牌在 3×1 槽中使用(0, 90, 80)。 - 错误的轮廓相对于槽(高瘦模型放在方形槽中:训练假人、盔甲架、旗帜杆)→ 没有旋转能解决这个问题;更换模型。
- 侧对 / 躺倒 / 背对相机 → 使用
- 在一次渲染中试听替换模型: 临时将几个现有物品指向候选预制体(
item.iconModel = candidate,override 为零),渲染,生成联系表,挑选。然后优胜者放入内容代码中——如果内容构建每次运行时重新分配模型,临时赋值会被覆盖。 - 将摆位记录在内容代码中,而不仅仅在资产上,这样“覆盖数据”重建时能保留它们。仅在物品没有自己的摆位时应用记录的摆位,这样在 Inspector 中手动调整的摆位就能保留。
- 重新渲染并生成联系表,直到每个图标一目了然。
可穿戴物品的良好模型来源: 静态模块化角色部件(例如 Synty Modular Fantasy Hero 的 Characters_ModularParts_Static/Chr_Torso_*_Static)制作胸部盔甲图标比盔甲架或训练假人等预制体好得多——它们能填满方形槽并让人立即认出是“盔甲”。角色附加预制体(头盔、肩甲、披风)适合较小的槽。静态部件使用资源包的普通纹理材质,因此会像任何预制体一样转换为你的着色器。
注意事项
- 预览场景没有环境光照或天空盒——如果没有补光和边缘光,远离主光源的一侧会渲染为黑色。
- 后期处理和 MSAA 会破坏透明通道。 在图标相机上禁用后期(色调映射/泛光会将透明通道写为 1),并使用超采样代替 MSAA。
- 设置
cam.scene = previewScene,否则相机会同时渲染打开的场景。 - 在实例上移除碰撞器、禁用动画器、粒子/轨迹/线条渲染器——VFX 子对象和绑定姿势动画器会膨胀包围盒或显示为拖影。
- 降采样时使用预乘,否则透明边缘会从清除颜色中拾取暗边。
- 蒙皮角色以绑定姿势(T 姿势)渲染;给它们一个
rotationOverride或一个已摆好姿势的预制体变体。 - 调色板纹理的低多边形模型如果其调色板纹理有 mipmap,会显示为灰色(请参阅
unity-asset-pack-extraction技能)。
文件
templates/Editor/ModelIconRenderer.cs-RenderBatch(IconJob[], Options)、IconJob(model, cells, pngPath, rotationOverride)、菜单 Tools > Icons > Render Selected Prefabs(为每个预制体在Icons/文件夹中生成 1×1 图标)。scripts/icon_sheet.py- 带标签的渲染图标缩略图联系表,可按名称过滤(需要 Pillow 库)。