"""Register the completed four-enemy batch from actual generation and QA receipts.""" import json from pathlib import Path ROOT=Path(__file__).resolve().parents[1] NAMES={'Hornlet':'小角怪','Dashlet':'疾跑怪','Shellhorn':'硬壳怪','HornCaptain':'角怪队长'} def append(path,text): with (ROOT/path).open('ab') as f:f.write(('\n'+text+'\n').encode('utf-8')) def main(): config=json.loads((ROOT/'Config/Art/StudioTrials/Enemies.json').read_text(encoding='utf-8'));rows=[] for recipe in config['actors']: actor=recipe['actor'];folder=ROOT/'Tools/output/studio_trial'/actor receipt=json.loads((folder/'trial.json').read_text(encoding='utf-8')) edit=json.loads((folder/'unity_verification.json').read_text(encoding='utf-8'));play=json.loads((folder/'play_verification.json').read_text(encoding='utf-8')) assert receipt['status']=='validated' and edit['status']==play['status']=='pass' rows.append(dict(actor=actor,name=NAMES[actor],source=recipe['source'],sourceTriangles=recipe['sourceTriangles'],studioTriangles=receipt['studio']['actual_faces'],triangles=edit['triangles'],bones=edit['bones'],height=recipe['height'],bindErrorMm=edit['bindError']*1000,soleVertices=len(receipt['soleFit']['blenderVertices']),maxTilt=play['maxTilt'],motionSamples=edit['rows'])) directory=ROOT/'Doc/Design/Character/StudioEnemies';directory.mkdir(parents=True,exist_ok=True) (directory/'batch_validation.json').write_text(json.dumps(dict(status='validated',actors=rows),ensure_ascii=False,indent=2),encoding='utf-8') table='\n'.join(f"| {r['name']} {r['actor']} | {r['sourceTriangles']} | {r['studioTriangles']} | {r['triangles']} | {r['bones']} | {r['height']:.2f}m | {r['soleVertices']} |" for r in rows) text='''# 剩余四敌人Studio低模/UV及原动作复用 2026-10-21完成。用户明确授权四份高模上传腾讯混元3D Studio,批处理配方 `Config/Art/StudioTrials/Enemies.json`。沿用大角首领已验证的2~5步,交付四个独立Studio版本;原版模型、Avatar、控制器和成品动画保留,未替换正式战场。 | 角色 | 源高模面数 | Studio UV面数 | 最终三角面 | 原骨数 | 高度 | 局部脚底校正顶点数 | | --- | ---: | ---: | ---: | ---: | ---: | ---: | '''+table+''' ## 制作过程 1. 官网Studio低模拓扑V1.5,三角面/低。逐角色上传自己的高模,再把精确下载的低模FBX提交Studio UV展开;保留任务ID、原始GLB/FBX/OBJ及UV布局PNG。 2. 烘焙前对齐Studio居中/归一化的网格和原高模,使用等比缩放、底面中心平移;UV哈希前后一致。角怪队长使用 `horncaptain_main.glb`,与原22骨的生成源哈希完全一致;原始50k及清理版均保留。 3. Blender在官网UV上烘焙1024²颜色/法线/AO/金属度/粗糙度。超过目标2000面的30%时再Collapse减面,保留UV层和贴图,不重复展开UV。小角怪得到1999面属于减面整数舍入,未添加无用面凑数。 4. Blender转回各自原骨架,应用各自原角色配方中的权重规则,最多4个归一化权重。候选Prefab直接引用原Avatar、原AnimatorController及原Clips/Idle、Walk、Attack;没有重新生成、重新收尾或复制成品动作。 5. 每角色重新检查实际蒙皮。仅在363帧约束中出现超过3毫米穿地的新脚底顶点才做游戏空间1毫米的局部几何校正;原骨骼、UV、动作与外层根Transform不变。无穿地的角色不套用大角首领的两个顶点编号。是否校正及数量以表格和每角色sole_fit.json为准。 ## 资产与验证 - 四角色根目录 `AIClient/Assets/Bundles/Characters/Enemy/{Actor}Studio/`,包含 `{Actor}Studio.prefab`、`{Actor}Studio_Enemy.prefab`、静态/蒙皮FBX、XPbr材质和1024² base/mix贴图。 - 独立场景 `AIClient/Assets/Bundles/Scenes/Review/Studio_{Actor}_Review.unity`;截图 `Assets/Screenshots/{actor小写}_studio_comparison.png`,1800×900,上原版/下Studio版,Static/Idle/Walk/Attack。场景以Additive生成、采样后关闭,不覆盖原角色总验收场景。 - 五敌人总览 `Assets/Screenshots/enemy_studio_batch_overview.png`,对应独立场景 `Studio_Enemies_Overview.unity`;包含先前大角首领,统一0.8m展示高度仅供视觉比较,实际角色Prefab尺寸仍为表中数值。 - 每角色均核对原骨路径和绑定局部TRS、原Avatar/控制器引用、原动作所有曲线绑定、蒙皮权重、底面和尺寸。绑定对照误差低于2毫米。 - 三动作各121帧,共每角色363帧、四角色1452帧:没有塌陷或无效顶点;底面在±3毫米内,循环接缝小于1毫米,动作可见,倾角小于25°。Attack保留原动作的短距离前冲,不视作外层根漂移。 - 同一次Play检查四个角色,各观察到Idle/Walk/Attack三状态、方向正确、外层角色根固定。原Prefab/控制器/成品动作/rig哈希再次复核一致。 - 生成与QA回执 `Tools/output/studio_trial/{Actor}/`:trial.json、hunyuan_studio.json、studio_*Rsp.json、bake_alignment.json、model_decimated.json、static_export.json、sole_fit.json、unity_verification.json、play_verification.json。以status=validated为最终状态。 ## 批处理复现 ```powershell python Tools/process_enemy_studio_batch.py --stage cloud python Tools/process_enemy_studio_batch.py --stage finish python Tools/process_enemy_studio_batch.py --stage play python Tools/process_enemy_studio_batch.py --stage verify ``` 云端阶段调用已安装的3D工作台集成,依赖已有项目登录会话;本次四模型外传已获明确授权。Unity资产、导入设置、Prefab、材质和场景均经Pipeline,显式指定AIClient项目。原始下载与中间件保持可追溯,结果作为独立候选供比较;最终同面数的画质和目标设备性能应分别评估。 ''' (directory/'Production.md').write_text(text,encoding='utf-8') marker='## 四敌人Studio低模与原动作复用完成(2026-10-21)' if marker.encode('utf-8') not in (ROOT/'Doc/ResDesc_Model.md').read_bytes(): append('Doc/ResDesc_Model.md',marker+'\n\n| Actor | High tris | Studio UV tris | Final tris | Bones | Height | Sole edits |\n| --- | ---: | ---: | ---: | ---: | ---: | ---: |\n'+table+'\n\n资源根目录 `AIClient/Assets/Bundles/Characters/Enemy/{Hornlet,Dashlet,Shellhorn,HornCaptain}Studio/`;各含静态Prefab/FBX、蒙皮FBX与Enemy入口、XPbr材质与base/mix。官网Studio低模/UV→Blender对齐烘焙→保留UV减面→各自原骨架绑定;原Avatar/控制器/三动作直接复用。Edit/Play及原资源哈希通过,正式战场未替换。详情 [StudioEnemies/Production.md](Design/Character/StudioEnemies/Production.md)。') append('Doc/ResDesc_Animation.md','## 四敌人Studio版原动作复用(2026-10-21)\n\n四个 `{Actor}Studio_Enemy.prefab` 直接引用各自原 `{Actor}_Animator.controller`、原Avatar及 `{Actor}/Clips/{Idle,Walk,Attack}.anim`;原成品动作文件哈希一致,本批无新增动画。小角怪/疾跑怪/角怪队长原22骨、硬壳怪原28骨;1452帧实际蒙皮采样、统一Play三状态/方向/外层根固定通过。报告 `Doc/Design/Character/StudioEnemies/Production.md`。') append('Doc/ResDesc_Picture.md','## 四敌人Studio贴图与对比图(2026-10-21)\n\n- `AIClient/Assets/Bundles/Characters/Enemy/{Actor}Studio/{Actor}Studio_base.png`/`_mix.png`:Hornlet、Dashlet、Shellhorn、HornCaptain各一套1024² XPbr,官网UV、Blender对齐高低模后五通道烘焙并打包,经Pipeline导入。\n- `AIClient/Assets/Screenshots/{hornlet,dashlet,shellhorn,horncaptain}_studio_comparison.png`:四张1800×900原版/Studio版静态与三动作对照,由Pipeline采样渲染并目视检查。\n- `AIClient/Assets/Screenshots/enemy_studio_batch_overview.png`:1800×900五敌人原版/Studio版总览;`Studio_Enemies_Overview.unity` 独立场景以0.8m展示高度比较,不修改实际角色尺寸。\n- 官网UV布局与五通道原稿位于 `Tools/output/studio_trial/{Actor}/`,详细来源与报告见 `Doc/Design/Character/StudioEnemies/Production.md`。') append('Doc/ResDesc.md','四个剩余敌人的Studio低模/UV、Blender对齐烘焙与原骨架三动作复用已完成,见 [StudioEnemies/Production.md](Design/Character/StudioEnemies/Production.md)。') append('Doc/Design/Character/EnemyCharacterProduction.md','## 四敌人Studio流程复验完成(2026-10-21)\n\nHornlet、Dashlet、Shellhorn、HornCaptain均按大角首领2~5步流程完成独立Studio版,绑定各自原骨架并直接复用原Avatar/控制器/三段成品动作。使用通用StudioTrial脚本按本角色骨数、尺寸及实际动作约束验收;禁止照搬大角首领骨编号或脚底顶点。生成、修正、Edit/Play及资源路径见 [StudioEnemies/Production.md](StudioEnemies/Production.md)。') catalog=ROOT/'Doc/ResDesc_Config.md';data=catalog.read_bytes();old='当前仅完成本地配方与来源/原动作前检,云端上传受自动审批拦截,正在等待用户确认这四份模型向腾讯混元3D Studio的外传授权;本条不代表四个Studio资产已完成。'.encode('utf-8');new='用户已明确授权四模型向腾讯混元3D Studio上传,四角色云端制作、本地绑定及Edit/Play均已完成;最终报告见 `Doc/Design/Character/StudioEnemies/Production.md`。'.encode('utf-8');catalog.write_bytes(data.replace(old,new)) print('Registered four validated Studio enemies and production report') if __name__=='__main__':main()