Claude 管规则,Codex 管实现,这两个工具前后一串,我最近用它们替一个项目搭了套 PCG 美术生产管线。原本要两周的植被投放,两天出了可用版本。这篇就记录整条管线的拆解、落地过程和踩过的坑。如果你也在做场景美术、技术美术,或者一个人扛整个游戏项目的美术产能,这篇可以直接当参考。
先解释一下标题:PCG 是 Procedural Content Generation,程序化内容生成。它不是扔随机数,而是用一套明确规则让内容自己长出来。美术生产管线则是从原画、建模、贴图、材质、场景装配到最终光照检查的整套流程。这两个词合在一起,就是在“场景装配”这个最耗人工的环节里,让程序和规则替代重复劳动。下面所有内容都来自我最近一次真实项目里的实操,不是从文档上抄来的概念。
1. 传统美术管线慢在哪:先拆三个隐性成本
1.1 手工摆放与重复劳动的时间黑洞
业界聊 PCG 的时候,大家首先想到的都是“雕塑感”“留白”“视觉引导”这些美术语言,很容易忽略一个底层事实:一大片区域的基础内容铺设,本质上是在做体力活。
我当时负责的项目是一块约 1 平方公里的开放区域,地形起伏、绿洲、戈壁、废弃建筑群都有。第一版完全靠美术手动摆放树木和石块,结果一周下来只铺了 40%,还出现了大量重复:同一棵树的朝向完全一致、石头间距像用尺子量过、角色可活动区域的植被密度和远处毫无差别。
这类问题不是美术同学偷懒,而是人手一张地图、一颗一颗摆模型的模式,天然带三个毛病:一是太慢,二是太均匀,三是改起来太痛。PCG 的核心价值不是“自动生成”,而是把重复劳动从人工挪到规则上,让人只处理真正需要审美判断的部分。
1.2 需求变更引发的二次返工
项目里最常见的一幕:玩法同学过来说“这片区域剧情要走,所以场景得清空一些”,或者“Boss 战需要一块 30 米半径的开阔地”。手工摆放的版本,得先让人找出那个范围内所有对象,再手动删、再手动调整边界。一次两次还行,一周改个四五次,美术同学心态基本就崩了。
我现在做的这套管线,解决这个问题的思路非常直接:所有生成物都带上规则标签。玩法要开口袋区域,我只需把规则表里加一个圆形排除区域,然后重新跑一次生成,程序自动跳过该范围,同时保留范围外已经放置且被手动调整过的东西。这种“规则可调、历史可保留”的机制,才是生产管线该有的样子。
1.3 AI 工具改变的是哪一段
以前要搞 PCG,得先找程序排期:提需求、写工具、调参数、做 UI,动辄一个月。工具写出来还经常不符合美术预期,再迭代两版,项目热度都过了。所以很多团队会选择放弃 PCG,继续用人力硬扛。
Claude 和 Codex 这类工具介入后,变化在于“规则设计”的成本被大幅压低。过去需要程序来翻译美术需求,现在 Claude 可以直接把美术的口头描述转成结构化规则表;过去需要程序一行行写生成脚本,现在 Codex 可以把规则表直接变成编辑器里的插件代码。关键路线从“人等程序”,变成“人和 AI 一起快速迭代”。
这不是说程序不重要了,恰恰相反,程序在架构设计、性能调优上的价值比以往更高。但 AI 确实把从“想法”到“工具初版”的周期,从以月为单位压到了以天甚至小时为单位。
2. Claude+Codex 分工蓝图:一个管规则,一个管实现
2.1 把两个工具当作“实习生”来用人
我的做法可能和很多人想象的不一样。我没有让 Claude 写代码,也没有让 Codex 做需求分析,而是把一个岗位拆成了两个人:Claude 当“规则助理”,负责把模糊的美术语言变成可执行的条目;Codex 当“实现助理”,负责把规则条目变成能跑的编辑器脚本。
你可以把 Claude 想象成技术美术,坐在电脑前跟场景美术聊需求,聊完输出一张张清晰的工作卡;Codex 则像初级程序,拿着工作卡去写实现。这两个角色放在一起,恰好是生产管线里最需要衔接的两个环节。
具体到我的实操,分工大概是这样的:
| 环节 | 谁主导 | 产出物 | 人工介入程度 |
|---|---|---|---|
| 需求采集 | 美术 | 原始口头描述 | 高 |
| 规则提取 | Claude | JSON/表格规则 | 低,但需要人确认语义 |
| 技术方案 | Claude + 人 | 伪代码、模块拆解 | 中 |
| 代码实现 | Codex | 编辑器脚本 | 中,需要人工审查 |
| 场景验证 | 人 + AI | 可调参数、生成结果 | 高 |
| 数据回流 | Claude | 修调建议 | 低 |
2.2 管线五个环节的输入输出映射
我把完整管线拆成五个环节,每个环节的输入输出都比较明确,这样才不会被 AI 的“自由发挥”带偏。
第一环节是规则制定。输入是美术口述,比如“绿洲边上密一点,越往外越疏,石头只出现在背阴坡”。Claude 的任务是把这些表述变成包含区域、范围、密度、坡度阈值、噪声阈值的规则表。第二环节是技术选型。Claude 会帮我决定用哪套生成逻辑,是采样法线分布还是根据地形高度过滤,并输出伪代码。
第三环节是代码实现。Codex 拿到 Claude 的规则表和伪代码后,在编辑器里写脚本。第四环节是集成测试,我在引擎里跑一遍,把结果截图发给美术确认。第五环节是参数回流,美术提意见后,我把意见再丢给 Claude 调整规则,Codex 再改对应代码。
这套流程的核心逻辑是:规则表是整个流程的中枢,人和 AI 都围着它转。规则错了,后面全错;规则对了,Codex 出的代码即使有小问题,修的也只是执行层面的问题,而不是方向性问题。
2.3 为什么要两个 AI 而不是只用一个
可能有人问:一个工具难道不能既做规则分析又写代码吗?我试过。把需求分析和长代码生成放在同一个上下文里,工具很容易“精神分裂”——长篇规则分析还没写完,就开始自动接代码,结果两边都不完整。
分开的好处是:Claude 的输出可以作为 Codex 的输入上下文,输入结构统一、字段明确,Codex 不需要从一堆对话里猜需求。反过来,Codex 运行报错时,我会把报错信息直接丢给 Claude,让它帮忙分析是 API 版本问题还是业务逻辑问题。
实操感受是,这两个工具不是“两个AI”,而是“两个不同擅长的实习生”。Claude 更像整理信息的,Codex 更像动手执行的。你不需要跟它们谈感情,只需要把输入输出标准化,它们就能协作得比较好。
3. 实操记录:用两天搭出一套 PCG 植被投放管线
3.1 第一步:用 Claude 把美术口头需求变成规则表
项目实际需求大概是这样:一片约 400x400 米的沙漠绿洲区域,中心是湖泊,绿洲周围要密集分布棕榈树,往外 100 米逐渐过度到低矮灌木和干草,仙人掌只出现在干燥区域,坡度超过 35 度的地方不放任何植被,角色主路两侧 3 米内清空。
我把这段原话丢给 Claude,并要求只输出可量化的规则,不接受描述性形容词。当时用的提示词大概是:
你是资深技术美术,下面这段需求是场景美术的原话: “绿洲边上密集一点,越往外越稀,石头只出现在山坡,坡度太大别放。角色经常走的路线附近不要有仙人掌,看着扎人。” 请输出一个规则表,每个规则必须包含可量化字段:区域、范围、密度、排除带、噪音阈值。不要给解释,只要规则。Claude 输出的规则表长这样:
{ "name": "Desert_Oasis_Rule", "assets": [ "Vegetation/Palm_Cluster", "Vegetation/Shrub_Desert", "Vegetation/Cactus_Desert" ], "density_curve": [ { "distance_m": 0, "density": 0.85 }, { "distance_m": 60, "density": 0.4 }, { "distance_m": 150, "density": 0.08 } ], "height_range": [10, 45], "slope_max": 35, "noise_scale": 0.002, "density_threshold": 0.5, "exclude_path_width": 3, "collision_off": true }注意几个细节:Claude 把“绿洲边上密集、往外变稀”翻译成了 density_curve 数组,把“坡度太大别放”翻译成了 slope_max 字段,把“主路附近清空”翻译成了 exclude_path_width。这就是我想要的,可以直接让 Codex 读取使用,而不是一段还需要人二次解析的文字。
一个实际建议:如果你让 Claude 自由发挥,它很可能会给你输出一大段方案,里面既有规则、又有材质建议、还有性能分析,看着很专业,实际没法用。一定要在提示词里强制约束“只输出规则、必须量化”,这种情况下一份干净的结构化配置比长篇大论有用得多。
3.2 第二步:让 Codex 按规则表把工具写出来
拿到 JSON 规则表后,我把它直接贴给了 Codex,并补了一条实现要求:
请在编辑器里实现一个 PCG 植被生成工具: - 读取 Desert_Oasis_Rule.json - 采样地形高度、坡度和 PerlinNoise - 按 density_curve 随距离衰减密度 - 跳过 exclude_path 范围内的放置点 - 生成物按 4 个格子分组,放到 Generated/Veg_Layer 空物体下 - 不要每棵树都挂碰撞体,不加光影烘焙标记 - 提供 Undo 支持和参数面板Codex 生成的 C# 脚本(示意版本,API 以实际引擎版本为准):
// 示意代码:以某商业引擎的编辑器脚本 API 为例,函数名不代表真实接口 [MenuItem("Tools/PCG/Generate Vegetation From Rule")] public static void GenerateVegetation() { var rule = RuleConfig.Load("Assets/Rules/Desert_Oasis_Rule.json"); if (rule == null) return; var terrain = SceneHelper.GetMainTerrain(); var candidates = AssetLibrary.Load(rule.assets); for (float x = rule.minX; x < rule.maxX; x += rule.step) { for (float z = rule.minZ; z < rule.maxZ; z += rule.step) { Vector3 pos = new Vector3(x, 0f, z); float height = terrain.SampleHeight(pos); float slope = terrain.SampleSlope(pos); float noise = Mathf.PerlinNoise(x * rule.noiseScale, z * rule.noiseScale); if (height < rule.heightRange.x || height > rule.heightRange.y) continue; if (slope > rule.slopeMax) continue; if (noise < rule.densityThreshold) continue; float dist = Vector3.Distance(pos, rule.oasisCenter); if (Random.value > rule.densityCurve.Evaluate(dist)) continue; if (PathHelper.IsNearMainPath(pos, rule.excludePathWidth)) continue; var prop = ObjectPlacer.Place(candidates[Random.Range(0, candidates.Count)]); prop.SetPosition(pos + Random.Range(-rule.jitter, rule.jitter)); prop.SetScale(Random.Range(rule.scaleRange.x, rule.scaleRange.y)); prop.GroupTo("Generated/Veg_Layer/" + Random.Range(0, 4)); } } SceneHelper.MarkSceneDirty(); }这段代码初看没什么大问题,但我在实际操作中不会直接跑,而是手动过一遍检查。当时我改了三个地方:
第一,把循环里反复调用的 AssetLibrary.Load 移到了循环外,避免每次生成都加载一遍资源目录;第二,给 Random 加了一个固定种子,方便问题回溯,不然每次跑出来的结果都不一样,很难排查规则问题;第三,生成了超过 3000 个对象后,编辑器会明显卡顿,我在代码里加了分帧处理,每次循环处理 200 个点后让出控制权。
3.3 第三步:引擎内联调,把结果变得可手改
第一次跑出来的结果,坦白说问题不小:湖泊周边密度确实出来了,但仙人掌长到了湖边潮湿区域的边缘,这和美术想要的“只在干燥区出现”有偏差。原因在于我给的规则表里,仙人掌的区域过滤维度只有高度和坡度,缺少湿度或距离湖泊距离的判断。
处理方式很直接:跟 Claude 沟通后,在规则表里加了一个 lakeDistance 字段,仙人掌的抑制距离设置为离湖 80 米。Codex 只加了一行判断,重新生成,这一条就解决了。整个过程耗时不到十分钟,这在传统手动摆放时代根本不敢想象。
这里有一个生产管线里的关键思路:生成结果必须“可手改,且手改结果不被后续重新生成覆盖”。所有程序生成的植被都放在 Generated/Veg_Layer/ 目录下,并在名字里带上 Gen_ 前缀。美术同学手动调整过的对象会被移到 Art_Tuned_ 目录,同时挂上一个 Tuned 标签。重新运行工具时,程序只处理 Generated 目录,不碰 Art_Tuned,这样可以保证人工修改和程序生成互不覆盖,管线才有实际可用性。
3.4 第四步:让数据回流,规则越调越准
第一次跑完后,美术提了一条意见:绿洲边缘应该有更多遮挡,最好是密到角色需要绕过的那密度。这是一条很典型的视觉引导需求,直接改 JSON 数字其实不太好表达。我当时做的事,是把美术这句话原封不动丢给 Claude,让它拆解成具体参数调整建议。
Claude 的回答是:把 density_curve 第一段从 0.85 提到 1.0,同时把绿洲边缘的 scale_range 调整为 [1.2, 1.8],让靠近湖边的大树视觉片段更强烈。Codex 改完这两个参数后重新生成,美术看完反馈“这回堵得有点太过,往回退一点”。最终参数是 0.92。
这套“规则表—生成—人工反馈—Claude 调参—Codex 改码”的循环,是整个管线最有价值的部分。它让你不再需要从一堆生成结果里手动改一百棵树,而是直接改规则源头,一次改动影响全局。
4. 常见问题与排查技巧实录
4.1 AI 生成代码第一次就编译通过?别信
“AI 写代码一次跑通”这种场景,我在实际项目里几乎没怎么遇到。最常见的问题是 API 版本差异:Codex 训练数据里的接口名和当前引擎版本对不上,生成的代码经常报“找不到类”或“参数数量不匹配”。
我的排查流程是这样的:先把完整报错信息原样贴给 Codex,问它“这是哪个 API 版本的变化,给一份该版本的替换写法”。如果它给的方案还是编译不过,我就把报错信息丢给 Claude,让它分析是命名空间问题还是调用时序问题。两个工具配合,大多数错误能在十分钟内定位。
但这不代表可以完全放心。AI 生成的代码里最危险的还不是编译错误,而是“看起来能跑但逻辑不对”的问题,比如资源泄漏、没有 Undo 支持、数据未分层。我给自己定了一条铁律:AI 生成的代码必须过四步审查,看 API 是否有过时警告,看资源加载是否在循环外,看生成物命名和分组是否符合规范,看是否有 Undo 和可回滚支持。这条流程帮我提前避免了好几次直接把美术场景搞乱的事故。
4.2 程序化结果“太假”的破解办法
第一次跑出的植被分布有个典型问题:远看很像回事,走近一看,树和树之间的间距几乎一样,好像有人拿尺子量过。这是很多 PCG 初稿的通病——生成逻辑太干净,缺少自然界的随机噪声。
破解办法我在实操里有三个。第一,把 PerlinNoise 的 scale 调大一些,让噪声波动的尺度覆盖整片区域的宽度,而不是细碎的小噪声。第二,加入密度抖动,在每个点的判断里乘一个 0.8 到 1.2 的随机系数,让最终分布的边缘不是一条清晰线,而是有过渡感。第三,也是我觉得最重要的,加入“手绘种子点”模式:美术在场景里手动点几个密集区中心点,生成规则围绕种子点做圆形分布衰减,而不是全图均匀撒点。这套方式下,美术的审美意图直接嵌进了生成逻辑,效果比纯调数字好一个量级。
4.3 我用过的排查速查表
| 现象 | 可能原因 | 排查思路 | 我踩过后的解决方式 |
|---|---|---|---|
| 生成结果一排排整整齐齐 | 随机种子固定或没用噪声 | 检查噪声采样是否参与判断 | 加入 PerlinNoise 并引入密度抖动系数 |
| 物体全都重叠在一起 | 高度采样点没做横向偏移,或半径冲突不检测 | 检查相邻点间距与模型边界 | 在规则表里加 step 和 jitter 参数,随机偏移放置点 |
| 手动调过的树又被覆盖 | 程序没有区分手改层 | 检查是否独立目录和标签 | 分 Generated 与 Art_Tuned 两层,程序只处理前者 |
| 场景数据巨大、卡顿 | 生成物未合批,颗粒物体过多 | 检查是否使用 GPU 实例化以及 LOD | 规则表加 lod 参数,远处使用低密度替代 |
| 结果仍和美术预期偏差较大 | 规则表语义太含糊 | 检查是否有不可量化字段 | 强制规则表只保留区间、阈值、布尔并行 |
| Codex 老生常谈地报编译错误 | API 版本不一致 | 贴完整报错,让 Claude 分析 | Split 错误信息,让两个工具分别从语法和逻辑两侧排查 |
这个表我一直放在手边,每次跑新的资产类型,先对照一遍,能省不少调试时间。
5. 管线搭完之后还能往哪扩展
5.1 横向扩展:从植被到其他美术资产
同一套“Claude 出规则,Codex 写工具”的方法,不只适用于植被,完全可以搬到贴花、石块堆、废弃建筑残骸、室内摆件等场景。管线逻辑不变,变的只是输入资产类别和规则字段。
我在这套管线后面接了一个“贴花自然过渡”的案例。美术需求是“外墙边缘要有风化痕迹,但窗户周边干净”。传统做法是手刷贴花,慢且不统一。用 Claude 拆规则后,Codex 写了一套工具,按照墙面法线和距离窗户的距离自动叠加污渍贴花,美术只需要事后看一眼有没有贴到不该贴的地方。这块原本预算是一周,实际两天做完。
5.2 纵向扩展:把资产审校也交给 AI
管线跑通后我发现,这套东西更值钱的应用是“自动审校”。传统美术生产里,资产提交前得检查贴图大小、命名规范、碰撞体开关、LOD 距离、是否落错图层,全是重复劳动,但又必须有专人盯。
我现在的做法是:让 Claude 定义一套可量化的资产规范清单,Codex 写批量检查脚本,每天跑一遍全场景资产,输出一份问题清单,美术顺着清单改就行。代码逻辑不复杂,但把流程管理者的工作从“重复盯”变成了“例外处理”,这才是管线层面真正提升效率的地方。
5.3 一点个人体会:别把 AI 当成替代者,当成效率杠杆
这套管线跑下来的真实体感是:AI 没有替代任何岗位,但它把“因为成本太高而放弃的做法”变成了可能。以前 PCG 工具开发是程序排期里的二等公民,现在一个人两小时就能搭出初版;以前美术改需求要等工具做改动,现在改规则表加跑一轮生成就行。
我个人的建议是,别一上来就搭一个大而全的管线,先拿一个最痛的点做最小闭环。我做植被投放的这个场景,从“原流程模拟”到“PCG 初版”只用了两天,但为了这套流程顺手,又花了两天做了手改层分离和批量导出。先跑通一个小闭环,再往其他资产类复制。这套思路是实操里最不会被项目需求反复击穿的方案,也是我下一次做其他类型管线时会继续沿用的一条路。