Add rank, friends, fishing, and camp treasure with T2 studio models and skill presentation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
udx
2026-10-21 23:01:31 +08:00
co-authored by Cursor
parent 89e0fa246f
commit 079313fb06
677 changed files with 395371 additions and 9692 deletions
@@ -0,0 +1,67 @@
# 伙伴技能特效与音效制作记录
2026-10-21:十位伙伴的技能表现已接入正式 `PrototypeArena`。本批补齐四条 TangoFlux 音效,九条计划音效均有真实产物及生成回执。
## 已制作资源
特效目录:`AIClient/Assets/Bundles/Combat/Partners/`。各行文件名均以 `Vfx_` 开头、`.prefab` 结尾。
| 伙伴 | 特效文件名 | 触发与形态 |
| --- | --- | --- |
| 石球 | RockBallGuard | shield:琥珀护环与石甲颗粒,跟随目标直到护盾耗尽/到期 |
| 火喵 | FireCatFlare | hit:火花与橙色冲击环;复用火焰蓄力、发射与弹道 |
| 芽芽 | BudBudBloom | heal:绿环、粉色花瓣与治疗十字 |
| 闪闪雀 | SparkBirdBolt | hit:连接施法挂点与命中目标的蓝色折线雷电 |
| 泡泡龟 | BubbleTurtleBubbles | slow:围住目标的蓝色泡泡 |
| 岩甲犀 | RockRhinoQuake | slow:贴地震波与飞散石块;石击沿用岩石命中 |
| 烈焰狮 | FlameLionBreath | ability release:面向目标的锥形喷焰;hit:火焰命中 |
| 藤灵 | VineSpriteVines | heal:上升藤蔓、叶片与绿环 |
| 雷纹豹 | ThunderLeopardClaw | hit:紫色雷电连接与三道爪痕 |
| 潮汐鲸 | TideWhaleTide | shield:半球水罩与涟漪,状态结束清理 |
Pipeline 同时制作六个共用低多边形网格:`SkillStone`、`SkillLeaf`、`SkillHealCross`、`SkillBubble`、`SkillWaterDome`、`SkillVineHelix`(`.asset`)。`PartnerSkillGlow.mat` 使用现有 `AIGame/EnemyCombatParticle` Shader,白纹理及顶点色;不修改敌人共用材质。所有 Prefab、材质、网格均在编辑器内持久化。
新增音效位于 `AIClient/Assets/Bundles/Sound/SFX/BattleSkills/`:
| 文件 | 用途 | 成品长度 | 实际 seed |
| --- | --- | --- | --- |
| Sfx_Heal.wav | 治疗 | 0.55s | 52005 |
| Sfx_Slow.wav | 减速 | 0.50s | 52007 |
| Sfx_Lightning.wav | 雷电命中 | 0.38s | 52008 |
| Sfx_EnemyHit.wav | 软受击 | 0.26s | 52009 |
按 `D:/UD/AI/XModel/TangoFlux_AI调用指南.md` 调用本地 `127.0.0.1:8012`。每条源音频2秒、50步、guidance 4.5,最多2条并发;65Hz高通、起音裁切、5ms淡入/50ms淡出、峰值约 -1.94dBFS。成品 PCM16/44.1kHz/双声道,Unity 导入为 PCM、DecompressOnLoad、保留采样率。源文件与请求缓存:`Tools/output/partner_skill_sfx/`;回执:`Doc/Design/Sound/BattleSkills/Partners/generation.json`;九条连听文件:同目录 `preview_all_nine.wav`。前五条保留 Slice 原始回执和真实 seed。本批未声称完成主观听审;发布授权审查沿用原 manifest 的 pending 状态。
## 标准制作与接入步骤
1. 在 `Config/Combat/partner_presentations_v1.json` 配置角色、效果索引、声音索引、地面效果、持续时间与池容量。数据效果仍由 `skill_runtime_v1.json` 的服务器逻辑决定。
2. 用 `BuildPartnerSkillFx.Build` 经 Unity Pipeline 制作/更新持久化美术资产,再用 `BuildBattleSkills.Build` 构建正式表现池并嵌入已有战场。
3. 声音按 TangoFlux 指南生成,保留 request/job/source/output 哈希;补登记 manifest,设置 Unity 导入参数。维护共用音效优先于按角色重复生成。
4. `BattleSkillPresentation` 仅消费已结算的 cast_start、release、projectile、hit、shield、heal、slow 等事件;原 Attack 仍按既有15种角色的 attackImpact 对齐。19个既有 SkillMuzzle 随角色朝向与T2缩放;表现组件不计算伤害/治疗/减速。
5. 验证索引与文件、音频格式及回执、真实轨迹、播放清理和画面,追加资源登记后完成。
正式池当前15类效果、76个根粒子实例、8个音源、9条音效、10个伙伴配置。雷电折线复用池中的 LineRenderer;运行时不创建材质、粒子或声音对象。雷电/群体治疗/减速同一次 cast 同种声音只播一次;普通软受击避免旧敌人声音与新伙伴声音重复叠播,硬壳/护盾反馈仍保留。
暂停与倍速作用于表现时钟及粒子;声音保留原始音高。过期的一次性事件跳过,未到期护盾和弹道可恢复。取消/死亡/目标消失/状态到期/battle_end/禁用均清理对应租约,代数标识避免旧租约停止刚复用的粒子。战斗结束保留计数供验收、清空播放对象。
## 验收证据
- `audio_config_validation.json`:十个配置与 Prefab、九条音效的源/请求/成品哈希、成功任务、起音/淡出/响度/零削波通过。
- `behavior.json`:十种专属效果与九种声音均触发;连接端点、多目标音效去重、超池复用、过期跳过、暂停/2倍速/静音、死亡/到期/取消/结束/禁用清理通过。23份既有服务器轨迹覆盖十个伙伴,全部回放至末尾无残留。
- `battle_visual.json`:真实 `PrototypeFlow` 消费服务器第20关T2轨迹并截图,验证正式战场、既有挂点和雷电命中。测试夹具不写真实账号。
- `Assets/Screenshots/partner_skills_overview.png`:十角色独立特效总览;`partner_skills_battle.png`:正式场景命中。已目视检查颜色、形态、源点到目标及亮背景可见度。
- `VerifyBattleRuntime.Assets`:正式战场76实例/8音源/9音效、19个局部-Z挂点、10伙伴/5敌人动作相位绑定通过。
- `python -m unittest discover -s Tools/tests -p test_skill_design.py`:8项通过;`python Tools/verify_partner_skills.py`、`python Tools/validate_skill_runtime.py` 通过。
尚未进行微信真机帧耗、内存与混音主观验收;本次为编辑器功能及视觉验收。本批不改服务器逻辑、数值或现有账号,未重启8080服务。收尾退出测试 Play,保留原编辑场景。
重建入口:
```text
python Tools/generate_partner_skill_sfx.py
Unity Pipeline: BuildPartnerSkillFx.Build -> BuildBattleSkills.Build
python Tools/verify_partner_skills.py
Unity Pipeline (Play): VerifyPartnerSkillFx.Behavior / ContactSheet
Unity Pipeline (Play): VerifyBattleRuntime.VisualSkills
Unity Pipeline (Stop): VerifyPartnerSkillFx.Finish / VerifyBattleRuntime.Assets
```
@@ -0,0 +1,92 @@
{
"status": "pass",
"profiles": 10,
"signaturePrefabs": 10,
"poolRoots": 76,
"voices": 8,
"audio": [
{
"id": "Sfx_FireCharge",
"seconds": 0.48,
"peakDb": -1.9386641491007355,
"rmsDb": -14.407821284878423,
"clippedSamples": 0,
"sha256": "686f9799eb264fcf310edb63dd69f75d16be94092bda40b3c341b0df18765217",
"actualSeed": 62100
},
{
"id": "Sfx_FireLaunch",
"seconds": 0.28,
"peakDb": -1.9386641491007355,
"rmsDb": -14.786814954199185,
"clippedSamples": 0,
"sha256": "e6f40a6d9a7e57f6fd56051c2393315c0610554921f5e26459eab2cbde40bbd2",
"actualSeed": 62101
},
{
"id": "Sfx_FireHit",
"seconds": 0.4,
"peakDb": -1.9386641491007355,
"rmsDb": -12.397172372455682,
"clippedSamples": 0,
"sha256": "d7c39fe8d2a270ab1241ee655f13d775f0e9c7cc0c3d38fdd6da2b33da493039",
"actualSeed": 62102
},
{
"id": "Sfx_RockHit",
"seconds": 0.32,
"peakDb": -1.9386641491007355,
"rmsDb": -17.7350875982902,
"clippedSamples": 0,
"sha256": "092735b139b22e0e5a1cd851c493fb1d6c9ff320cfdd33fdefc73db725a37a59",
"actualSeed": 62103
},
{
"id": "Sfx_Heal",
"seconds": 0.55,
"peakDb": -1.9386641491007355,
"rmsDb": -14.50466159857536,
"clippedSamples": 0,
"sha256": "61ab8a7cd7feed49646752ad921c50dbfbec33ce8d3b534d4451f3638ff5df89",
"actualSeed": 52005
},
{
"id": "Sfx_Shield",
"seconds": 0.65,
"peakDb": -1.9386641491007355,
"rmsDb": -14.618990028368117,
"clippedSamples": 0,
"sha256": "52119154552ac4fbbde0d94d34011be1749c019dec3764c31ecb7fae1b8fff37",
"actualSeed": 62104
},
{
"id": "Sfx_Slow",
"seconds": 0.5,
"peakDb": -1.9386641491007355,
"rmsDb": -18.172440503372695,
"clippedSamples": 0,
"sha256": "e191cc6baa46fa6e1c46f77eaa072495c52b4c75d47be98cfd7a81ca14a134c9",
"actualSeed": 52007
},
{
"id": "Sfx_Lightning",
"seconds": 0.38,
"peakDb": -1.9386641491007355,
"rmsDb": -15.270460646000476,
"clippedSamples": 0,
"sha256": "a8e6f806b3e62e8916929d39b63f9d6cfd1f534dc44f49f79d99a490753ed00a",
"actualSeed": 52008
},
{
"id": "Sfx_EnemyHit",
"seconds": 0.26,
"peakDb": -1.9386641491007355,
"rmsDb": -17.505279728308555,
"clippedSamples": 0,
"sha256": "2cdb0a6f272f1bd5fac3ffab34fffaa52104a38056debe944e7913d7cf6ef93f",
"actualSeed": 52009
}
],
"subjectiveListening": "not_asserted",
"releaseLicenseReview": "pending_upstream_review_per_guide"
}
@@ -0,0 +1,10 @@
{
"status": "pass",
"authoritative": true,
"persistentMuzzles": 19,
"t2ScaleApplied": true,
"flight": false,
"signature": true,
"effects": 14,
"networkAccountWrites": false
}
@@ -0,0 +1,191 @@
{
"status": "pass",
"profiles": 10,
"effectKinds": 15,
"poolRoots": 76,
"voices": 8,
"audioClips": 9,
"signatureEffectPlays": [
3,
1,
0,
2,
0,
1,
1,
1,
17,
1,
1,
2,
1,
1,
1
],
"soundPlays": [
3,
2,
2,
1,
2,
2,
2,
15,
1
],
"chainSoundOnce": true,
"beamEndpoints": true,
"poolReuse": true,
"pause": true,
"speed2": true,
"staleSkip": true,
"death": true,
"expiry": true,
"cancel": true,
"mute": true,
"endCleanup": true,
"disableCleanup": true,
"traceCases": 23,
"traceActors": 10,
"rows": [
{
"trace": "stage_10_t1_f1.json",
"events": 2894,
"effects": 225,
"sounds": 156
},
{
"trace": "stage_11_t1_f2.json",
"events": 2225,
"effects": 143,
"sounds": 121
},
{
"trace": "stage_12_t1_f0.json",
"events": 2338,
"effects": 174,
"sounds": 157
},
{
"trace": "stage_13_t1_f1.json",
"events": 3380,
"effects": 285,
"sounds": 196
},
{
"trace": "stage_14_t1_f2.json",
"events": 2458,
"effects": 184,
"sounds": 158
},
{
"trace": "stage_15_t1_f0.json",
"events": 2587,
"effects": 215,
"sounds": 198
},
{
"trace": "stage_16_t1_f1.json",
"events": 3626,
"effects": 361,
"sounds": 262
},
{
"trace": "stage_17_t1_f2.json",
"events": 2512,
"effects": 195,
"sounds": 167
},
{
"trace": "stage_18_t1_f0.json",
"events": 2866,
"effects": 240,
"sounds": 210
},
{
"trace": "stage_19_t1_f1.json",
"events": 3321,
"effects": 311,
"sounds": 221
},
{
"trace": "stage_1_t1_f1.json",
"events": 2920,
"effects": 185,
"sounds": 133
},
{
"trace": "stage_20_t1_f2.json",
"events": 2738,
"effects": 237,
"sounds": 210
},
{
"trace": "stage_20_t2_f0.json",
"events": 2476,
"effects": 193,
"sounds": 179
},
{
"trace": "stage_20_t2_f1.json",
"events": 3099,
"effects": 254,
"sounds": 177
},
{
"trace": "stage_20_t2_f2.json",
"events": 2488,
"effects": 180,
"sounds": 159
},
{
"trace": "stage_2_t1_f2.json",
"events": 2001,
"effects": 110,
"sounds": 105
},
{
"trace": "stage_3_t1_f0.json",
"events": 1758,
"effects": 98,
"sounds": 88
},
{
"trace": "stage_4_t1_f1.json",
"events": 3005,
"effects": 198,
"sounds": 133
},
{
"trace": "stage_5_t1_f2.json",
"events": 2188,
"effects": 134,
"sounds": 120
},
{
"trace": "stage_6_t1_f0.json",
"events": 2171,
"effects": 131,
"sounds": 111
},
{
"trace": "stage_7_t1_f1.json",
"events": 2770,
"effects": 204,
"sounds": 139
},
{
"trace": "stage_8_t1_f2.json",
"events": 2004,
"effects": 116,
"sounds": 97
},
{
"trace": "stage_9_t1_f0.json",
"events": 2199,
"effects": 151,
"sounds": 133
}
],
"networkAccountWrites": false
}
@@ -0,0 +1,7 @@
{
"status": "captured",
"profiles": 10,
"screenshot": "AIClient/Assets/Screenshots/partner_skills_overview.png",
"sampleSeconds": 0.14,
"networkAccountWrites": false
}