ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PSD转游戏UI自动化:从设计稿到Prefab的四段式管线

PSD转游戏UI自动化:从设计稿到Prefab的四段式管线 1. 为什么PSD转游戏UI不能靠“切图手动拼”1.1 传统工作流到底慢在哪游戏UI的生产流程绝大多数团队到现在还是这么转的美术在PSD里画好界面切图导出PNG然后发给客户端同学客户端对着设计稿在引擎编辑器里手动摆放调整锚点、摆对齐、设置九宫格、改字号颜色。一张中等复杂度的界面美术画两三天客户端还原也要小半天如果中间设计改了再重来一轮。这个过程的问题不在于“谁不努力”而在于“信息重复传递”。PSD里明明已经包含了元素的位置、尺寸、层级关系、颜色、圆角、描边、字体大小但到了引擎那边这些信息全部变成了设计师眼睛里的参考值需要人肉再敲一遍。人肉环节越多误差越大位置偏几个像素、字号差了1号、颜色深了一点点这些在单个界面里看不出来但同屏多个界面放在一起粗细深浅不一致品质感就下去了。所以我一直在想能不能把“PSD”本身当作一种中间数据格式来用美术把设计稿画完程序把它的图层结构、坐标、样式信息批量读出来再加上美术提前约定好的命名规范直接生成引擎里的UI结构。新思路的核心就一句话把PSD从“参考图”变成“数据源”让UI还原从人工抄写变成自动化转换。1.2 自动化的核心矛盾设计师的自由度和程序的约束先说清楚PSD自动转游戏UI这事不是今天才有工具能做到。Photoshop的ExtendScript可以写脚本导出图层Unity也有PSD Importer这类插件国外还有一些商业工具在做类似的事。但真正落到项目里你会发现一个根本矛盾设计师在PSD里的表达是高度自由的而程序解析需要的是高度确定的规则。同一张按钮美术可能用图层样式做投影也可能单独画一层黑色半透明形状放在下面圆角矩形可能用形状图层也可能直接贴一张png。这些做法在视觉上差别不大但程序解析图层的时候处理逻辑完全不同。如果没有任何约束自动化工具面对十个设计师的十种画法就只能全部“拍平”成图片导出来布局信息还是拿不到。所以这条新思路的第一步不是写代码而是定规矩。美术资源要按一套约定好的分组结构、命名规则、图层类型规范来制作程序脚本才能稳定地把图层信息解析出来。本质上这是在设计师自由度和程序可解析性之间找一个平衡点美术不用改变画图的习惯但图层组织和命名必须遵守规范。1.3 新思路的整体框架我实践下来的整体框架是四段式源头规范、自动解析、中间描述、引擎还原。先说源头规范。美术在PSD里按规则分层、分组、命名。比如按钮必须有“bg/icon/text”三个子层级九宫格必须在图层名里标注好可拉伸区域文本图层必须用指定字体。这件事靠文档约束是没用的得把规范做成检查脚本保存前跑一遍不合规就报错。然后是自动解析。用脚本批量读取PSD的图层树把每个图层的名称、类型、位置、尺寸、旋转、透明度、混合模式、图层样式全部抽取出来同时也导出切图资源。注意这里不是简单的“导出所有可见图层”而是根据命名规则智能识别哪些图层是独立元素、哪些是背景的一部分、哪些要单独切片。第三步是生成中间描述文件实际就是一份结构化UI描述可以是JSON、XML或者YAML。它记录了界面的完整层次哪个Panel下挂了哪些子节点每个节点的锚点、偏移、尺寸、九宫格参数、图片资源引用、文本内容、字号颜色。这份文件不依赖任何引擎格式PSD转一次可以同时提供给Unity、Godot或者自研引擎使用。最后是引擎侧还原。在Unity里写一个编辑器导入器读取JSON描述自动创建Panel、Image、Text、Button等组件设置RectTransform的锚点和偏移挂上对应图片和九宫格参数。如果命名规范到位还原出来的界面和设计稿的重合度能达到95%以上剩下的微调工作量非常小。这套框架的好处是每一环都可以独立替换。今天用Photoshop明天换Figma只要中间描述文件的格式不变引擎侧完全不用动。引擎从Unity换成Godot只需要重写导入器。这也是我推荐大家按这个思路做而不是直接找一份“PSD转Unity”现成插件的原因——插件通常是封闭的难以适配项目自己的规范和引擎版本。2. 源头规范让PSD从设计稿变成“可解析的数据文件”2.1 图层命名是第一个关口很多团队做UI自动化失败第一个坑就栽在命名上。设计师习惯了“图层 1 拷贝 3”“形状 5”这种名字程序脚本读出来一脸懵这个图层到底是要做按钮背景还是装饰线条所以规范里第一优先级就是命名规则。我的做法是给图层名加“类型前缀”脚本靠前缀来决定这个图层的用途。比如“btn_bg”表示按钮背景“btn_icon”表示按钮图标“txt_title”表示标题文本“img_deco”表示装饰图片“sld_bg”和“sld_fill”表示滑块的底和填充。前缀体系是透传的UI类型是Button子节点就都带btn_前缀UI类型是Slider子节点就带sld_前缀。这样脚本解析图层树时先通过前缀判断元素类型再根据子图层的标准命名找到对应组成部件。这里有一个关键经验不要在命名里写“坐标”或者“尺寸”比如“btn_bg_100_50”这种。PSD里图层的位置和尺寸本来就能读出来写进名字纯属冗余而且一旦美术移动了图层名字就语义错乱。命名里只表达“用途”和“类型”不表达“状态值”。还要注意命名统一用英文小写加下划线。中文命名在Windows环境下的Photoshop里没问题但导出到Unity时资源文件名带中文容易出幺蛾子某些平台打包还会报错。字体、特殊字符、空格、括号全都不允许出现在图层名里。2.2 分组结构和九宫格约定命名解决的是“这个图层是什么”分组结构解决的是“这个图层属于谁”。我要求每个完整的UI控件必须是一个组组的名字就是控件名。比如一个设置界面里的“音量滑块”对应的是一个组组名“sld_volume”。组下面的子图层按照之前说的前缀命名背景sld_bg、填充sld_fill、滑块图标sld_thumb。不同控件各自独立成组组与组之间不要嵌套超过三层嵌套越深解析脚本的逻辑越复杂出错的概率越高。九宫格是UI还原里最容易出错的地方。美术画了一个圆角矩形按钮到引擎里设置Sliced后圆角会不会被拉伸完全取决于九宫格切得对不对。我在规范里的做法是凡是需要九宫格拉伸的图层在图层名末尾加“9”标记并且把可拉伸区域信息记录在一个专门的文本文件里或者通过图层的矢量蒙版边界来推算。具体到实现我比较推荐的是“命名标记边界推算”组合。美术在按钮背景图层名里写“btn_bg9”脚本解析到9后缀后读取这个图层的像素内容分析四角的透明区域自动计算出安全的九宫格边界。纯色圆角矩形的识别率非常高但带描边的按钮计算出来可能偏一点这种情况我允许设计师在图层名里显式标注内边距比如“btn_bg9_inset24”表示四周各留24像素的圆角保护区域比自动推算更省心。2.3 参考分辨率、锚点和对齐信息怎么表达PSD里的图层只有绝对坐标没有“锚点”和“对齐”的概念。但游戏UI必须要处理不同分辨率下的自适应比如一个“返回按钮”应该永远贴在屏幕左上角一个“金币数量文本”应该始终在顶部居中。如果转换出来的UI用的是绝对坐标换一个分辨率就全乱了。所以我规定画布最外层必须有一个参考分辨率的分组节点标明这个PSD的设计尺寸是750x1334还是1920x1080。脚本拿到这个尺寸后结合引擎侧传入的屏幕分辨率才能计算缩放比例和锚点基准。锚点信息从哪来我的方案是约定一个“九宫格定位法”每个控件组的位置不是看它的绝对坐标而是看它相对于父容器边界的关系。脚本计算控件的中心点相对于父容器四条边的距离如果左边距和右边距大致相等就判定为水平居中如果中心点x小于父容器宽度20%判定为靠左。判定规则写死一套转出来的UI天然带有锚点信息。这套自动判定的准确率大概在八成到九成剩下的需要导入引擎后手动微调。但就算有10%需要调整也比从头手动摆放一整块界面省太多时间了。而且锚点判定规则是可以迭代的某个控件判断错了手动修正后在描述文件里标明“这个节点用显式锚点不走自动判定”后续重新导入就不会再错。3. 自动化管线PSD解析、切图导出与布局信息抽取3.1 工具链选型JSX、psd-tools还是ag-psd想从PSD里抽出图层结构目前主流有三条路Photoshop内置的JSX脚本、Python的psd-tools库、Node.js的ag-psd库。我三种都用过说说各自的适用场景。JSX脚本在Photoshop进程里跑最大的优势是可以直接调用PS的渲染能力导出切片、读取图层样式、获取文本图层的实际渲染效果。但它必须在装有Photoshop的机器上运行而且每张图都要启动PS来处理批量几十上百个文件的时候速度比较慢。适合做“人工在PS里检查并导出”的半自动场景。psd-tools是纯Python库不依赖Photoshop解析PSD的速度非常快能读取图层名、位置、尺寸、透明度、混合模式甚至能提取文本图层的内容和样式信息。我在服务器上批量处理整个项目的PSD文件用的就是它。注意图层样式和智能对象的支持没有PSD完整偶尔会有分辨率偏差需要写兼容逻辑。ag-psd是纯JS方案能跑在Node环境甚至浏览器里解析能力很全连PSB大文件都支持。它的特点是解析结果本身就是像素数据可以抽样分析图层内容。我做过一个方案浏览器里拖入PSD后端解析完直接返回UI描述JSON前端预览还原效果整个工具做成Web应用设计师在浏览器里就能调整参数重新导出。我的建议是如果你只是想把图层树信息和切图资源批量取出来psd-tools综合成本最低如果要做成团队在线工具让设计师持续使用并迭代选ag-psd搭Web端JSX脚本则适合做保存前自动检查和切图前的预处理。3.2 切图导出与九宫格标注的处理布局信息只是其中一半另一半是切图资源。很多团队的痛点在于一个界面几十个图层美术手动隐藏显示、挨个导出PNG效率极低。自动化的思路是直接读取图层边界把每个需要导出的图层单独渲染成PNG。用psd-tools处理时核心逻辑是遍历图层树根据命名规则判定哪些图层需要导出、哪些只是辅助参考不需要导出。例如以“bg”“icon”“thumb”结尾的图层需要导出“辅助线”“占位符”等名称开头的图层直接跳过。注意导出的时候要记录图层在设计稿坐标系里的绝对位置而不是相对位置因为还原UI时需要的是全局坐标。九宫格标注我这边是生成一个伴随的JSON文件每条记录对应一张图片。假设一张按钮背景图叫“btn_bg”九宫格对应的是四个数值单位是像素左边距、上边距、右边距、下边距。如果是自动推算的脚本会从四个边缘向中心扫描跳过透明像素找到第一个不透明像素的位置连续扫描几条线取最小值这样能避免个别噪点导致的偏差。如果是美术显式标注的“inset24”就直接读取数值。这一步有个小坑Photoshop里图层的边界是包含透明像素的一个图层如果边缘有一两个像素的透明边导出的PNG尺寸就会比视觉上大一圈。psd-tools默认导出的是“整个图层边界”而不是“可视内容边界”。所以我在导出前会先对图层做一次透明像素裁剪遍历像素alpha通道找到最小包围盒再按这个包围盒裁剪。这样引擎里挂的图片尺寸和设计稿上看到的视觉尺寸才一致。3.3 描述文件设计与生成描述文件是整个管线的核心产物我把它设计成树状结构和UI的视觉层级一一对应。顶层是画布信息包含参考分辨率、缩放比例往下是根节点再往下是各个Panel、容器、控件。每一条节点记录大概长这样节点名、节点类型Panel/Image/Text/Button/Slider等、矩形区域left、top、width、height全部基于参考分辨率、锚点信息anchorMin、anchorMax、offsetX、offsetY、图片资源路径、九宫格参数、文本内容、字号、字体、字色、对齐方式、透明度等。这个描述文件的格式建议用JSON原因很简单各个引擎和脚本语言读JSON都方便调试的时候人也能直接看。但要注意版本管理问题PSD改了一版重新生成的描述文件最好和资源一起提交到版本库客户端和美术都能看到UI结构的变化而不是只看一张设计图对比。生成描述文件的逻辑里有个关键处理合并冗余节点。PSD里一个视觉元素可能由多层组成比如同一个按钮的背景由底部阴影层、主体圆角层、顶部高光层三层叠出来的。这三层如果逐层导出成三张图片引擎还原时就会出现层级复杂、处理耗性能的问题。所以我在规范里鼓励设计师把这类复杂效果合并成智能对象或者单一图层。如果确实没合并脚本要把它们烘焙成一张图导出而不是各自独立。3.4 从PSD到Prefab的还原过程描述文件生成后引擎侧的工作其实就简单了。我拿Unity举例导入器的核心是一个Editor脚本读JSON递归遍历节点树用GameObject和RectTransform把控件创建出来。具体的映射逻辑是这样的JSON里的节点类型Image对应Unity的Image组件Text对应TextMeshPro或者Unity UI TextButton对应Button组件的挂载。锚点信息直接填到RectTransform的anchorMin、anchorMax、pivot和anchoredPosition。图片资源由脚本通过Resources.Load或者Addressables加载九宫格参数设置image.type为Sliced并赋值四个边距值。这个导入过程我跑了实际项目测试过一个包含三十多个控件的复杂界面引擎侧从解析JSON到生成完整Prefab耗时基本在毫秒级。最花时间的反而是图片导入和资源加载但那些也是自动化完成的。整套管线跑完一张中等难度的UI界面从拿到PSD到引擎里能看到可交互的还原界面十分钟之内能搞定。而且我建议把“自动导入”做成批处理整个项目的所有界面一次性全部导入生成对应的Prefab。好处是曝光问题很快哪张图路径配错了、哪个九宫格数值异常批量导入时日志里全都会冒出来集中修复比一张一张等回报快得多。4. 绕不开的坑混合模式、图层样式与字体4.1 图层样式怎么处理最省事PSD里的图层样式是自动化流程里最不省心的部分。投影、内发光、描边、渐变叠加在Photoshop里都是参数化的有图层样式面板可以调整。但到了引擎里这些效果要么通过额外的Shader实现要么就得烘焙成贴图完全没有参数化保留的可能。我的处理策略很简单能烘焙就烘焙不能烘焙就让美术去掉。投影、外发光这类不太依赖内部结构的样式让Photoshop脚本直接对图层内容做效果渲染然后导出成带透明通道的贴图引擎这边挂上就能显示视觉上基本一致。而内阴影、图案叠加这类需要根据背景实时变化的样式烘焙成贴图反而限制后续美术迭代我干脆规定设计师不要用。这说明一个现实问题自动化和美术质量之间是需要取舍的。我见过一些团队为了100%还原PSD效果导入引擎后还挂了一堆专用Shader项目运行性能明显下降得不偿失。我的建议是在接入自动化的第一版就明确限定图层样式使用范围允许投影、外发光、纯色描边禁止复杂的内发光和渐变叠加。这套规则写进检查脚本导出前自动检测不通过就不让出资源。4.2 字体和文本图层最容易翻车的环节文本图层是另外一个大坑。PSD里的字体美术机器上装了但项目组其他人电脑上不一定有就算都有Unity的默认字体渲染和Photoshop的文字渲染差异也很大字体不一样、字距不一样、行高不一样还原出来总有差异。我的经验是界面上重要的标题、数字能做图片就做图片避免走文字渲染。尤其是那些带描边、带特殊效果的艺术字直接让美术转成PNG一劳永逸引擎显示效果和设计稿完全一致。普通的说明性文本、动态数值必须用文字组件的话统一接入项目的字体管理方案字体的回退逻辑做好尽量使用项目里已有的字体不要跑到美术机器上装字体来复现。字号和行高的问题也有解法。解析PSD文本图层时psd-tools能读出fontSize和lineHeight。但这里有一点要注意Photoshop的行高是包含行距的和Unity Text组件的lineSpacing计算方式不一样。直接搬数值会导致多行文本的行距偏大或偏小。我在脚本里做了转换Unity的lineSpacing设为(fontSize lineHeight * 0.8) / fontSize用起来效果好很多但不同字体略有差异还是需要美术配合微调。文本图层的自动定位也是难题。Photoshop里文本框的锚点基准在左上角而Unity的Text组件pivot默认在中心。解析的时候要把文本框的位置偏移到中心点否则文本会上下左右偏移。这个偏移量不是固定的跟文本字号的基线有关我的脚本用了近似值生成的Prefab文本位置基本准确个别字体特殊的大标题需要手动微调。4.3 特殊效果与动效的取舍UI还原还有一个经常被忽略的问题Photoshop是静态设计工具输出的是“某个时刻的静态画面”而游戏UI有大量动效需求——按钮按下有缩放反馈、面板弹出有缓动动画、列表滚动有惯性效果。这些动效无法从PSD里直接解析出来。我的建议是动效信息单独维护不要在PSD层面做文章。自动化管线解决的是“静态还原”的部分动效由引擎侧的动画系统或者状态机来处理。比如按钮组件导入后我直接在生成Prefab的脚本里挂上按压缩放动画onPressed缩放到0.95释放回弹。这些是标准化的行为不需要每一张UI单独配置。如果PSD里某个控件是“待做动效”的我的做法是在图层命名里加一个“fx_”前缀脚本识别到这个前缀后在描述文件里给这个节点加一个“动画占位”标记。引擎导入器看到标记就自动挂一个Animator组件美术后续在引擎里给它做动画。这样整个流程既保证了静态布局的自动化又不限制后续动效创作的灵活性。5. 实操笔记与排查实录5.1 典型问题一导出图集边缘出现白边这个我踩过不止一次。用psd-tools切图导出PNG后放到引擎里sliced模式拉伸时边缘出现一条半透明的白边。排查下来是透明像素裁剪的算法问题png导出默认会把透明区域变成黑色再混合alpha裁剪边界附近如果有半透明像素就会被混入黑色。处理办法是在裁剪后做一次“去黑边”操作扩展几像素把纯透明像素替换为边缘颜色的半透明像素。我用的是Pillow的resize加边缘扩展实测能解决90%的白边情况。5.2 典型问题二解析速度慢到无法接受一批PSD文件第一次批量解析时我跑了整整半小时才出结果完全没法用。后来发现瓶颈不是图层解析而是导出每个图层像素时频繁调用底层图像解码。优化方案是批量复用打开的文件句柄并启用内存缓存同一张PSD多次访问同一图层时不再重复解码。优化完速度提升了将近十倍一批五十个文件十分钟内能跑完。5.3 典型问题三九宫格被裁切导致拉伸变形自动推算的九宫格在圆角非常小或者梯形按钮上会算错。圆角太小扫描时阈值设置过严把圆角区域当成透明部分裁掉导出的图片圆角直接变成直角拉伸时四个角的保护区域不对变形很严重。后来我的处理是自动推算结果和美术显式标注可以共存自动推算只做初值导入工具的界面上允许手动查看和修改九宫格的四个值改完保存到描述文件。这样美术对自动化结果有控制权心里有底大家合作才顺畅。5.4 日常维护规范建议自动化管线不是写完代码就完了它需要持续维护。我建议团队里至少指定一个人负责规范管理和工具迭代尤其是规范的新增和修改一定要走评审。因为改一个命名规则可能影响项目里所有已经转换过的PSD。每次版本发布前跑一遍批量检查未按规范命名的图层数量、导出失败的资源清单、描述文件里缺失的关键字段。这些检查要写进CI流程一旦有检查项失败就阻断发布。经验是规范的执行比规范的制定难十倍自动检查脚本是让规范真正落地的最有效手段。我目前这套方案跑下来团队里美术和程序的配合磨合期大概花了三周之后UI制作的效率提升非常明显。美术改完设计稿重跑一遍管线新版本UI几分钟就同步到引擎里联调和返工的时间大幅压缩。如果你也在被PSD到游戏UI的高成本还原折磨哪怕不按我这套全套方案来先把“命名规范图层结构约束”做起来后续再逐步加自动化收益也会很明显。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进