JSG01 雙拳 2P
沒有走位、沒有距離、沒有連招表。出拳要真的揮,防守是把那隻手舉著(持續姿勢,不是按一下)。 舉左手只擋得住打你左邊的拳 —— 攻方猜「他會守哪邊」,守方猜「他會打哪邊」,整局就是這一件事的反覆。
1核心循環:擋下 → 破綻 → 反擊
整場最賺的一筆不是「打中」,是「用單手擋下」。全部設計工作、動畫最吃重的部分,都圍繞這個迴圈。
用單手擋下對手一拳,他就會有 1.5 秒舉不起手。 這段時間你兩邊都能打、不用猜左右,傷害還 ×2.5。
1000 + 1400 + 720 = 3120 傷害= 對手血量的 19.5% —— 成功五輪就 KO。
單防=技術,雙防=硬吃。整個設計的支點就在這裡。
📌 破綻剝奪的是防禦,不是操作 —— 出破綻的人手還揮得動,可以賭一把繼續打。 演出要讀得出「他守不住了」,不能讀成「他不能動了」。
2還要知道的四件事
| ⚡ 體力 | 全場唯一資源,猜對回、猜錯掉。出拳要花體力,一直舉著手龜著也會扣 —— 龜防不是安全策略。 |
| 😮💨 力竭 | 體力見底就出拳變慢、傷害減半,而且不能防禦 —— 最想龜的時候,規則不准你龜。但仍然可以出拳,不會變成站著等的死時間。 |
| 👁️ 第一人稱 | 每人 960×1080。看得到對手正面與自己的兩隻手,看不到自己的身體。雙防會擋住自己的視野,這是第三人稱做不出來的代價。 |
| 🏆 勝負 | 血歸零 KO,或 90 秒時間到比血量。分數不參與勝負,只進結算頁與雙人紀錄。 |
3這一版做什麼
✅ v1 要做
- 四手環同時連線 + 配對 UX
- 揮拳偵測(統合 Andros 2.4)、舉防姿勢偵測
- 體力經濟、防禦分邊、破綻窗口、力竭與 Fever、連段
- 拳種傷害差異化(直/勾/上鉤,2026-08-25 拍板改為 v1 要做)
- 左右分割雙第一人稱 + 20 支新動畫 + 新擂台
- 2P HUD、側邊條、開場收場字卡、結算頁
- 7 支雙人教學影片
⏸️ v1 不做
弱點系統、教學關卡、擋下=時機窗口、完美防禦、累進式 cooldown、落後補償、排行榜。 七項的判決與理由都在「⚙️ 技術規格 → §3 明確否決 / 不進 v1」,那張表是唯一權威。
4檢查點與交付節奏
| 檢查點 | 程式 | 美術 | 驗收 |
|---|---|---|---|
| CP1 | 四裝置移植正式環境、規則層手抄、四台 BLE 壓測 | 動畫 10 支(待機/左右防/雙防/左右直拳/被打中 ×2/擋下 ×2)、擂台白模 | 遮字測試、反擊率量測、真人局長重訂 hpMax(同一場收完) |
| CP2 | 表現層、HUD、結算、教學頁 | 動畫 10 支(鉤拳/上鉤拳/架開/破綻/力竭/勝負)、背景+UV貼圖+烤光、10 特效、10 音效、服裝雙色 | 功能確認 |
1玩家操作
兩人各戴兩隻手環,畫面左右分割、各自第一人稱。你看得到對手正面,看得到自己的兩隻手,看不到自己的身體。
| 攻擊 | 揮拳。同一隻手揮完要收回才能再揮,收回前再揮=白揮(扣體力、打不到人)。左右手各自計時,所以左右交替可以打得很密 |
| 防守 | 舉起手並維持著。舉左手只擋得住打你左邊的拳 —— 這是全場唯一的即時博弈 |
| 雙手都舉 | 可以,兩邊都擋得住。但要付五重代價,見 §4 |
2擋下判定
拳打到的那一瞬間,看守方對應那一側的手有沒有舉著。有 → 擋下;沒有 → 命中。
3體力經濟 —— 全場唯一的資源
玩家要記的只有一句:猜對就回體力,猜錯就掉體力。
| 你做的事 | 體力 | 白話 |
|---|---|---|
| 出拳 | 扣 | 揮拳本身就要花力氣 |
| 打中 | 回(淨賺) | 扣掉出拳成本後仍然是賺的 |
| 被擋 | 重扣 | 全場最虧的一筆 —— 把拳送進對方防禦裡 |
| 挨打 | 扣 | |
| 擋到 | 回一大筆 | 但有每秒上限,不然「站著擋」會變永動機 |
| 舉著手卻沒擋到東西 | 每秒持續扣 | 🎯 這是治龜防的主藥:舉著不動不是免費的 |
| 站著什麼都不做 | 每秒微扣 | 堵住「兩個人站著互瞪」的死局 |
4防禦與雙防五重代價
舉手防禦有兩個限制:只擋得住一邊,以及舉太久會自動放下(放下後有短冷卻,那段空檔是刻意留給對方的)。
雙手都舉起來當然擋得住兩邊,但要付五重代價 —— 五條要一起存在,少一條雙防就會變成最佳解:
① 遮住自己的視野
第一人稱自帶的代價:手擋在臉前面,你就看不清楚對手要做什麼。
② 減傷差很多
單防擋下只吃 25% 傷害,雙防要吃 60% —— 雙防吃的傷是單防的 2.4 倍。不是完全不減傷,所以「打雙防」對攻方仍有收益,雙防不會變成免疫。
③ 擋到也不回體力
單防擋到會回一大筆體力,雙防擋到一毛都不回。
④ 空防扣三倍
舉著卻沒擋到東西時,雙防的體力扣得比單防快三倍。縮著不動撐不久。
⑤ 擋到不會產生破綻
只有單防擋下才能把對手打出破綻(§5)。前面四條是雙防的懲罰,這一條是給單防的獎勵。
5破綻窗口 —— 擋下之後的反擊機會
用單手擋下對方一拳,對方就會露出 1.5 秒的破綻。這是整個遊戲的爽點來源。
| 破綻期間,出破綻的人 | 被抓到的人可以 |
|---|---|
| 1.5 秒舉不起手(完全防不了) | 兩邊都能打,不用猜左右 |
| 手還揮得動 —— 可以賭一把繼續打,或收手吃完這 1.5 秒 | 打進去的傷害 ×2.5 |
6力竭與 Fever
力竭 —— 體力歸零就會「累到動不了那麼順」
力竭不會禁止你操作,只是每件事都變差:
| 效果 | 白話 |
|---|---|
| 出拳變慢(收拳時間 1.8 倍) | 節奏被拖住,對手有時間讀你 |
| 傷害減半 | 打得到也不痛 |
| 不能防禦(仍可出拳) | 🎯 你最想縮起來的時候,正好是規則不准你縮的時候(2026-10-02 起,取代原本的「只舉得起一隻手」) |
Fever —— 對手力竭的那一刻,我方的獎勵
這是「我把他打累了」的具體回報:持續 2 秒,傷害 ×1.5。
| 什麼時候進 | 對手「剛進入力竭」的那一瞬間,而且我方體力 ≥ 5000(體力上限 14000,約 36%) |
| 什麼時候結束 | 2 秒倒數跑完;或我方自己也進入力竭 → 當場強制解除 |
所以它獎勵的是「把他打到力竭的時候,你自己還有餘力」。 如果你也是拼到見底才把他磨垮,那一刻你體力不足 5000,就拿不到這 2 秒。
7連段與傷害
連續命中會越打越痛。KO 來自「連讀對幾次」,不是慢慢磨血。
| 第幾記命中 | 傷害倍率 | 實際傷害 | 說明 |
|---|---|---|---|
| 第 1 記 | ×1.0 | 400 | 基準 |
| 第 2 記 | ×1.4 | 560 | 連段真正的價值從這裡開始 |
| 第 3 記以後 | ×1.8 | 720 | 封頂,不會再往上 |
🎯 所以連段實際上是在逼你左右交替:同一隻手要 1 秒才收得回來,只用單手連打只剩 0.2 秒餘裕,漏一拍就斷; 左右交替則想打就打。這剛好就是「兩隻手環」這個裝置的核心優勢。
傷害還會被這些放大縮小
| 情況 | 倍率 | 什麼時候 |
|---|---|---|
| 打進破綻 | ×2.5 | 對手處於破綻中(§5)—— 全場最大的一筆 |
| Fever | ×1.5 | 我在 Fever 狀態 |
| 力竭 | ×0.5 | 我在力竭(不是對手) |
| 拳種 | ×1.00 ~ ×1.05 | 直拳 400 / 勾拳 410 / 上鉤拳 420 |
| 被擋(單防) | ×0.25 | 擋下仍會掉一點血,純防守會慢慢流血 |
| 被擋(雙防) | ×0.60 |
🔴 直拳不可以是傷害最低的那一個。直拳最好打、手環對直拳辨識最準、玩家又直覺以為上鉤最痛 —— 三個因素疊起來,會讓小孩固定吃最低值、懂的人固定吃最高值,自動把跨度吃滿。
8勝負與計分
勝負:只看血量
血歸零 KO,或 90 秒時間到比血量。分數不參與勝負。
分數:表現指標
給結算頁與雙人紀錄用,不改變任何一格血量、不進排行榜。
怎麼算分
數次數就好,跟傷害沒有關係。
分數 = 命中次數 × 10 + 擋下次數 × 15 − 被擋次數 × 5
分數量的是「你讀對幾次」,不是「你打掉多少血」。兩件事分開算,不要互相牽扯。
| 事件 | 分數 | 為什麼是這個方向 |
|---|---|---|
| 單防擋下 | +15 | 🎯 比打中還高 —— 這是核心迴圈的起點,也是最難教會的行為,分數要把它說出來 |
| 打中 | +10 | 基本盤 |
| 被擋 | −5 | 猜錯要有代價(約打中的一半) |
| 舉著沒擋到(空防) | 0 | 體力那邊已經在每秒扣了,不重複懲罰 |
分數不會低於 0 —— 被擋扣到負的就停在 0。
⚠️ 運動量/卡路里照平台原樣回傳 —— 「2P 有自己的分數」不等於可以不接平台那條。
技術規格
1完整運算規格
逐條對照 forge FightRules.cs 的實際實作。這一節是「每個系統到底在算什麼」。
dt=一個 tick 的時間;攻=出拳方、守=挨拳方。
所有數值為 ×100 尺度(同 §9 數值表)。
8-1. 一個 tick 的結算順序
順序是有意義的 —— 體力先被事件加減、再跑每秒扣款,最後才判斷力竭。
1. 姿勢更新 各計時器 −dt(破綻/連段窗口/收拳鎖/防禦冷卻/前搖) 2. 白揮扣款 拳沒收回又揮 → 扣 punchCost,不產生判定 3. 出拳結算 前搖倒數歸零的那一 tick 才結算(雙方同 tick 出拳則兩邊都結算) 4. 被動體力 力竭的自回 → 擋格預算回補 → 空防扣/站樁扣 5. 力竭判定 體力 ≤ 0 → 進入力竭;體力 ≥ 上限×0.4 → 脫離力竭 6. Fever 判定 對手「這一 tick 剛進入力竭」且我方體力 ≥ 5000 → 我方進 Fever 7. Clamp HP 夾到 [0, hpMax]、體力夾到 [0, staminaMax]
8-2. 出拳與命中判定
// 揮拳當下 if (該手收拳鎖 > 0) → 白揮:扣 punchCost,不打人也不會被擋,直接結束 else → 收拳鎖 = punchRecoverSec × (力竭 ? 1.8 : 1) 前搖 = Clamp(punchWindupSec, 0, 收拳鎖 × 0.8) // 前搖倒數歸零的那一 tick 攻.體力 −= punchCost 守方該擋的那一側 = 鏡射 ? (左↔右) : 同側 擋下 = 守方那一側此刻姿勢 == Guard
| 關鍵 | 說明 |
|---|---|
| 力竭會拖慢收拳 | 收拳鎖 ×windedPunchRecoverMul 1.8 —— 拳打得出去,但節奏被拖住,對手有時間讀你 |
| 前搖有隱藏夾子 | Clamp(前搖, 0, 收拳 × 0.8) —— 只拉前搖不拉收拳會被靜靜夾住,看不出來 |
| 命中在前搖結束那一刻 | 不是揮出去的第一幀。守方在前搖期間看得到拳在飛(=動畫第 30 幀) |
| 破綻中的守方擋不到 | 破綻期間舉不起手,所以 擋下 恆為 false —— 破綻=真的沒得防 |
8-3. 傷害
// 打中 傷害 = punchDamage × 連段 × Fever × 力竭 × 破綻 × 拳種 // 被擋(沒有連段,且連段當場歸零) 傷害 = punchDamage × 吃傷比 × Fever × 力竭 × 拳種
| 乘數 | 值 | 條件 |
|---|---|---|
| 連段 | 1.0 / 1.4 / 1.8 | 取「這一拳之前」已連幾記,第 3 記起封頂 |
| Fever | exhaustDamageMultiplier 1.5 | 攻方在 Fever |
| 力竭 | windedDamageMul 0.5 | 攻方在力竭(不是守方) |
| 破綻 | opening.damageMultiplier 2.5 | 守方處於破綻 |
| 拳種 | 400 / 410 / 420 | 直拳 / 勾拳 / 上鉤拳 |
| 吃傷比 | 單防 0.25 / 雙防 0.60 | 被擋才有 |
🔴 被擋也會掉血(單防吃 0.25)—— 純防守會慢慢流血,這是防龜防的一環,不是 bug。
8-4. 體力收支
體力收支 —— 事件型與每秒型的完整帳
事件型(發生就結算一次)
| 事件 | 誰 | 體力 | 備註 |
|---|---|---|---|
| 出拳 | 攻 | −800 | 不論命中與否都先扣 |
| 打中 | 攻 | +1800 | 淨 +1000(扣掉出拳成本) |
| 被擋 | 攻 | −400 | 再扣一筆,淨 −1200 |
| 挨打 | 守 | −1000 | |
| 擋到 | 守 | +2500 | ⚠️ 受每秒預算限制,見下 |
| 白揮 | 攻 | −800 | 拳沒收回又揮 —— 純扣,拿不到回沖,也不會被擋 |
每秒型(持續扣/回)
// 依序執行,同一 tick 可能同時成立 if (力竭) 體力 += windedRecoverPerSec(2500) × dt ← 疊加,不是取代下面的扣款 擋格預算 = min(1800, 擋格預算 + 1800 × dt) ← 擋到回復的每秒上限 if (任一手舉著) 體力 -= emptyGuardPenaltyPerSec(600) × dt ← 空防:舉著就在扣 × (雙防 ? 3.0 : 1.0) ← 🔴 雙防的空防扣款是三倍 else if (沒在出拳動作中) 體力 -= idleDecayPerSec(200) × dt ← 站樁
正解:舉著手力竭,就是回得慢。
min(2500 × 雙防係數, 剩餘預算),預算每秒最多回補 1800。
收支平衡點 54.5% 是怎麼算出來的
收支平衡點怎麼算出來的
打中淨 = −800 + 1800 = +1000 被擋淨 = −(800 + 400) = −1200 求 p 使期望值為零: p × 1000 + (1−p) × (−1200) = 0 2200p = 1200 p = 54.5%
猜對率低於 54.5%,一直出拳在體力上就是虧的。對手隨便舉一隻手就有五成擋率,
所以這個門檻刻意壓在「略高於盲猜」—— 要贏得靠讀對,但不至於讓進攻必虧。
⚠️ 舊版曾是 84.6%,那時進攻幾乎必虧,是 3b 人測「有回復機制也起不來」的根因。
8-5. 防禦、破綻、力竭、Fever 的狀態機
| 狀態 | 進入條件 | 離開條件 |
|---|---|---|
| 舉防 | 玩家舉手 且 該手冷卻 ≤ 0 且 未處於破綻 (力竭的時候兩手都不能舉) |
放下手;或撐滿 3 秒強制放下並進冷卻 0.5 秒 |
| 破綻 | 單防擋下一拳 且 攻方破綻冷卻 ≤ 0 且 攻方不在破綻中 → 攻方進破綻 1.5 秒、冷卻 4.5 秒 |
1.5 秒倒數結束 |
| 力竭 | 體力 ≤ 0 | 體力 ≥ staminaMax × windedExitRatio = 14000 × 0.4 = 5600 |
| Fever | 對手這一 tick 剛進入力竭 且我方體力 ≥ 5000 | 2 秒倒數結束;或我方進入力竭時強制解除 |
- 破綻冷卻 4.5 秒不是可調的舒適度 —— 它讓門戶大開的時間佔比維持在
1.5 ÷ 4.5 ≈ 33%。拉短會變成死亡螺旋換皮。 - 力竭的出口是體力門檻,不是計時器。計時器出口=「打到力竭 → 領免費體力 → 再打」,掃描實測進攻 bot 勝率會飆到 80~100%。
8-6. 連段
打中 → 連段 +1,窗口重設 = comboWindowSec(1.2s) 窗口歸零 → 連段歸零 被擋 → 連段當場歸零(不等窗口) 揮空 → 不影響連段(但扣體力) 倍率 = comboMultipliers[clamp(連段數, 0, 2)] // 取「這一拳之前」的連段數
| 第幾記 | 倍率 | 累計 |
|---|---|---|
| 1 | 1.0 | 400 |
| 2 | 1.4 | 960 |
| 3 | 1.8 | 1680 |
| 4 以後 | 1.8(封頂) | 每記 +720 |
8-7. 勝負
KO → 任一方 HP ≤ 0
時間到 → matchDurationSec(90s) 到,比雙方剩餘 HP
// 分數不參與勝負判定(見 §7)
2數值表 —— FightConfigAsset
全域平衡走 ScriptableObject(Inspector),不進企劃表。只有天然多列的東西進 Excel:多國文字、拳種傷害 3 列(400/410/420)。見 DEC-JSG01-003。
config.jsonjsg-prototype-forge/prototypes/jsg01-dualfist-2p/config.json(2026-08-14 定版,×100 尺度)。
⚠️ 另外兩處的數字都不是定案值:FightConfig.cs(只是 JSON 缺鍵時的 fallback)、proposal.md 那張表(3a 舊值,之後三輪都大改過)。
出拳三欄=動畫合約,不是平衡旋鈕
出拳三欄=動畫合約(clip 60 幀、命中掛第 30 幀)
動畫 clip 全長 60 幀,命中判定掛在第 30 幀(前後各半)。秒數只是幀 ÷ 60fps 的另一種寫法。
| 欄位 | 值 | 等價寫法(RD 真正要做的事) |
|---|---|---|
input.punchWindupSec | 0.50 | 命中判定掛在出拳動畫第 30 幀 |
input.punchRecoverSec | 1.00 | clip 全長 60 幀;這段期間同一隻手再揮=白揮(扣體力、不產生判定) |
幀 ÷ 60fps 的另一種寫法。兩邊是同一個數字 ——
動畫 key 60 幀 + 判定掛第 30 幀就自動對上,不用兩邊各記一組。
⚠️ 規則層有隱藏夾子 windup = Clamp(前搖, 0, 收拳 × 0.8) —— 只拉前搖不拉收拳會被靜靜夾住。
其餘欄位
FightConfigAsset 全部欄位與值30 項
| 分組 | 欄位 | 值(×100) | 備註 |
|---|---|---|---|
| 體力 | staminaMax | 14000 | |
punchCost 出拳成本 | 800 | ||
punchHitRegen 打中回復 | 1800 | 淨 +1000,全場唯一讓進攻可持續的正收入 | |
blockedPenalty 被擋懲罰 | 400 | ||
takeHitCost 挨打 | 1000 | ||
blockSuccessRegen 擋到回復 | 2500 | ||
blockRegenCapPerSec 每秒上限 | 1800 | 沒有它「站著擋」是永動機 | |
emptyGuardPenaltyPerSec 空防每秒扣 | 600 | 治龜防的主藥 | |
doubleGuardEmptyPenaltyMultiplier 雙防空防倍率 | 3.0 | 🔴 雙防五重代價之一。曾被誤判成死參數刪掉,2026-08-25 掃描抓回(刪掉=雙防勝率 40%→58%)。⚠️ 不要拿它調平衡,它是懸崖不是滑桿 —— ×3.5 會掉到 13.3%、×4.0 又跳回 48.0%。見 §9 下方說明 | |
idleDecayPerSec 站著不動每秒扣 | 200 | 堵「站著瞪」 | |
| 力竭 | windedExitRatio | 0.40 | 回到體力上限四成才解除 |
windedPunchRecoverMul | 1.8 | 收拳變慢 | |
windedDamageMul | 0.5 | 傷害減半 | |
windedGuardDisabled | true | 力竭期間不能舉防(取代原 windedSingleGuardOnly) | |
| Fever | feverSec / feverThreshold | 2 秒 / 5000 | |
| 防禦 | guard.maxHoldSec / cooldownSec | 3.0 / 0.5 | 冷卻硬區間 [0.3, 0.6] |
doubleGuardRegenRatio | 0 | 雙防不回體力 | |
progressiveCooldown | false | 累進式冷卻列 v2,見 §10 | |
| 減傷 | block.damageRatio 單防吃傷比 | 0.25 | ✅ 2026-08-25 拍板+掃描驗證 0.15→0.25。3000 局實測進攻 bot 59.3%(判準 <70%)。校準點見下方 |
doubleGuardDamageRatio 雙防吃傷比 | 0.60 | ✅ 2026-08-25 拍板+掃描驗證 1.00→0.60,雙防吃的傷是單防的 2.4 倍。代價:雙防 bot 勝率 33.2%→40.0%(3000 局),已據此重訂 baseline | |
| 破綻 | opening.durationSec / cooldownSec | 1.5 / 4.5 | 冷卻要跟著窗口走:門戶大開佔比= duration ÷ cooldown ≈ 33% |
opening.damageMultiplier | 2.5 | ||
opening.singleGuardOnly | true | 只有單防擋到才產生破綻 | |
| 勝負 | match.hpMax | 16000 | 🟡 CP1 當天真人局長重訂 |
match.punchDamage 每拳基礎傷害 | 400 | 🔴 不是 bot 專用 —— 所有人的傷害起點,見 §8 公式 | |
match.matchDurationSec | 90 | ||
exhaustDamageMultiplier | 1.5 | ⚠️ 實際語意是「我在 Fever 時加傷」,建議改名 feverDamageMultiplier | |
comboMultipliers | [1.0, 1.4, 1.8] | 見 §7 | |
comboWindowSec | 1.2 | ||
| 鏡射 | MirroredBlocking | true | ✅ 已定案 |
| 吃傷比 | 減傷 | 每記傷害 | 整局全擋累計 | 佔 hpMax | |
|---|---|---|---|---|---|
| 單防 | 0.25 | 75% | 100 | 13500 | 84% |
| 雙防 | 0.60 | 40% | 240 | 32400 | 203%(撐不完) |
(整局=90 秒 × 對手約 1.5 拳/秒 ≈ 135 拳全部擋下;每記=punchDamage 400 × 吃傷比)
- 雙防吃的傷是單防的 2.4 倍 —— 這是「打雙防對攻方仍有收益」的來源,雙防因此不會變成免疫
- 單防 0.25 之下,純靠單防硬撐整局會流掉 84% 血(0.15 時是 51%)。防守不再是免費的
⚠️ 門檻綁樣本量不能混用;改完任何數值都要重跑掃描。
三種樣本量的完整判準數字400/1000/3000 局
| 樣本 | 龜防 | 雙防 | 進攻 | 站樁 | 亂揮 | 易位 | KO | bot 局長 | 單防率 |
|---|---|---|---|---|---|---|---|---|---|
| 判準 | <30% | 見下 | <70% | <20% | <35% | ≥60% | ≥60% | 37.5s ±25% | >20% |
| 400 局 | 10.0% | 45.0% | 63.8% | 0% | 0% | 62% | 96% | 37.4s | 76% |
| 1000 局 | 7.0% | 41.5% | 61.5% | 0% | 0% | 61% | 95% | 37.5s | 76% |
| 3000 局 | 6.5% | 40.0% | 59.3% | 0% | 0% | 62% | 95% | 37.6s | 76% |
⚠️ 龜防/雙防/進攻三項會隨樣本量單調變化(400 局一律讀得比較「危險」)。 門檻綁樣本量,不能混用。
⚠️ 改完任何數值都要重跑掃描,不能只檢查比值 —— 比值按定義就與尺度無關,驗不出行為變化。
stamina.doubleGuardEmptyPenaltyMultiplier = 3.0 不要拿它調平衡doubleGuardDamageRatio(平順單調:1.00→33.2%/0.60→40.0%)。
🔴 也不要把它當死參數刪掉 —— C# 初值 1f 看起來像沒作用,但權威是 JSON 的 3.0;刪掉會讓雙防勝率從 40% 竄到 58%。
FighterState.damageMul 不要建進資產檔block.opponentStaminaDrain—— 宣告過但沒有任何 code 讀它。會變成「被擋額外扣守方體力」,而守方擋成功本來是回體力,方向相反block.windowMs—— 同上。它叫「擋下窗口」,會讓人實作成時機窗口,而那正是 §2 明確否決的設計。死參數取了一個像被否決設計的名字,就不只是沒用,是會把那個設計復活
📌 判斷一顆參數死活要看 JSON + 程式引用,不能只看 C# 初值 —— doubleGuardEmptyPenaltyMultiplier 就是這樣被誤判成死參數的(見上)。
config.json 凍結成快照,之後不要再改它、也不要建立「兩邊同步」的習慣。
3明確否決 / 不進 v1
附理由,避免下游重提。
| 提議 | 判決 | 理由 |
|---|---|---|
| 擋下=反應時機窗口 | ❌ 否決 | 反應時間 + 四台延遲,做了就是逼玩家做不到的事 |
| 減傷(單防以外再加一層) | ✅ 保留 | 🔴 2026-08-25 推翻舊結論。「疊上空防懲罰會過頭」來自 3a 的 F 組(×1 尺度、舊經濟、還沒有力竭/破綻/連段)。現行經濟下 3000 局重掃:單防 0.25 讓進攻 bot 只走到 59.3%,離判準 <70% 還有 10.7pp。見 §9 與 KB DEC-JSG01-023 |
| 累進式 cooldown | ⏸ 列 v2 | 見下方展開 |
| 落後補償(rubber-banding) | ⏸ 先不做 | 見下方展開 |
| ✅ 改為 v1 要做 | 2026-08-25 拍板,推翻原本的「v1 排除」。規格見 §7 | |
| 弱點系統 | ❌ 不做 | 2P 直接排除(1P 專屬機制) |
| 完美防禦(對方出拳前才舉手給更多獎勵) | ❌ 否決 | 2P 沒有時機可抓 —— 對手是真人、隨時可能出拳、沒有任何預告。而且玩家自然反應是提早舉手一直舉著,要他為了完美防禦故意先不防、賭最後一刻,等於叫他冒著挨打的風險賭博 |
v2 備案:累進式 cooldown 與落後補償 —— 為什麼現在不做
累進式 cooldown(程式已寫、開關關著)
防禦冷卻隨連續舉防次數變長,而不是固定 0.5 秒:
冷卻 = guard.cooldownSec × clamp(1 + 0.5 × (連續舉防次數 − 1), 1, 4)
連續第 1 次=0.5s、第 2 次=0.75s、第 3 次=1.0s……最多 4 倍(2.0s)封頂。
連續次數存在 FighterState.consecutiveGuards[],v1 只統計不使用。
落後補償 / rubber-banding
落後方暗中獲得加成(原本設想的形式:空防懲罰隨體力遞減)。這是防死亡螺旋的第三道防線。
| 層 | 手段 | 狀態 |
|---|---|---|
| 1 結構層 | 破綻冷卻(防「擋到→破綻→再擋到→再破綻」連鎖) | ✅ 已做 |
| 2 經濟層 | 力竭後回復比例、擋到回復上限 | ✅ 已做 |
| 3 備案層 | 落後補償 / 空防懲罰隨體力遞減 | ⏸ 先不做 |
啟用判準兩條,兩條都不達標才啟用:
| 判準 | 目標 | 現況 |
|---|---|---|
| 每局攻守易位次數 | ≥ 1 次(掃描口徑 ≥60%) | ⚠️ 未達標 1000 局 60%(邊界),40 局重跑基準線只有 54% |
| 從落後 30% 逆轉到 50% | ≥ 1 次 | 待真人局 |
sweep-results-3c.md 的 62% ✅ 是 12 局跑出來的假陽性,40 局重跑基準線是 54%。
通則:判準卡在邊界(±5pp 內)的項目,12 局樣本不足以下結論。依紀律仍不預先加補償,等 CP1 真人數據再判斷。
1動畫清單 —— 20 支,男女共用一套
Jacfitness_Art/JSG01/Character/Animation_DualFist2P/JSG01_2P_*.fbx(裝的是原型現在用的那支,覆蓋前可先播一次)
⚠️ 在 feat/jsg01-dualfist-2p-arena-handoff 分支,還沒合回主線。
CP1 交付(10 支)
待機
第 0 幀=出拳 clip 的第 0/60 幀,所有動作的接點。
舉左防
持續姿勢。正面要一眼讀出左右。
舉右防
雙防
原型無素材 雙手要遮住自己視野(第一人稱的感官代價)。
左直拳
60 幀,命中第 30 幀。
右直拳
⚠️ 直接 key 在頭高(原型那支是打身體、靠程式抬升)。
被左拳打中
沒有「正面打中」 —— 受擊只吃攻方用哪隻手。
被右拳打中
要做出力度分級(一般/破綻中/連段)。
擋下左邊來的拳
⚠️ 防禦那隻手要留在原位,動了會被讀成「沒擋到」。
擋下右邊來的拳
CP2 交付(10 支)
左勾拳
三種拳從第一人稱要一眼分得出來(硬需求 ⑥)。
右勾拳
正式版新增
左上鉤拳
全新 形狀可參考 BF_F_Box_LUpCut_V02。
正式版新增
右上鉤拳
全新 形狀可參考 BF_F_Box_RUpCut_V02。
左手架開
全身動作+往前壓半步,28 幀、無蓄力無回程(硬需求 ⑦)。
右手架開
不能只做一支鏡射 —— 軀幹朝向是相對那隻手編的。
破綻
原型無素材 雙手張開上舉+軀幹後仰,90 幀 hold pose(硬需求 ④)。
力竭(力竭)
肩膀起伏、護手垂下、重心變沉。力竭與暈共用一支。
勝利
切場事件:無淡入、強制切換。
敗北
| 什麼時候播 | 演什麼 | |
|---|---|---|
| 擋下反應 | 每次擋到都播,雙防也會 | 身體的小幅反應。⚠️ 防禦那隻手要留在原位 |
| 架開/反擊 | 只有單手擋下才播(那一下會打出破綻) | 全身動作 + 往前壓半步,要讀得出「是我把他架開的」 |
2時間規格 —— key 動畫的時候照這個
一律以 60 fps 製作。30fps 在 0.89 秒只有 27 幀,關鍵幀太擠。
出拳:一支 clip 整整 1 秒 = 60 幀
| 階段 | 幀 | 要做出什麼 |
|---|---|---|
| ① 蓄力(拉回) | 0 → 12 | 重心後移、肩膀拉後、拳往回收。對手就是靠這段讀出「他要打了、打哪邊」 |
| ② 揮出 | 12 → 30 | 加速甩出去。前段還能忍住,最後 5~8 幀才把行程一口氣吃完 |
| ⚡ 命中判定 | 第 30 幀 | 拳伸到最遠的那一幀。RD 在這一幀結算傷害 |
| ⏸ 命中定格 | 30 → 34 | 引擎加的,不要 key —— 打中 4 幀/被擋 3 幀/揮空沒有。key 進去會疊成兩倍 |
| ③ 收回 | 30 → 60 | 先快收、尾巴慢慢安定。第 60 幀要回到跟第 0 幀相同的架式,才接得回待機 |
建議關鍵幀(60fps)
出拳的建議關鍵幀(60fps)
| 幀 | 姿勢 |
|---|---|
| 0 | 架式(=待機姿勢,要能無縫接進來) |
| 6 | 開始拉回 —— 重心後移、肩膀轉開 |
| 12 | 蓄力最深(拳最靠身體、肩膀轉到最開)← 這是對手要讀的那一幀,要待得住 |
| 18 | 拳離開身體、手肘開始伸 |
| 26 | 加速段(拳過肩線) |
| 30 | 命中 —— 完全伸展(⚡ 傷害在這一幀) |
| 42 | 收回一半、重心回正 |
| 54 | 接近架式 |
| 60 | 回到架式(=第 0 幀) |
階段長度是硬的(引擎照這個切),中間的關鍵幀是建議 —— 快慢分布自己拿捏,只要第 12 幀待得住、第 30 幀完全伸展、第 60 幀回到第 0 幀就對。
其他動作
其他動作的時間規格3 項
| 動作 | 秒 | @60fps | 備註 |
|---|---|---|---|
| 受擊 | 1.00 | 60 f | 跟出拳一樣長。挨打後玩家一出手就會被打斷,所以這 60 幀是「被打了而且沒反應」時才播完 |
| 破綻(要維持住) | 1.50 | 90 f | 需要停得住的 hold pose,不是一閃而過。進入 + 維持 + 恢復 |
| 架開/反擊 | 0.47 | 28 f | 短、俐落,沒有蓄力也沒有回程。第 0 幀就是往外的軌跡、最後一幀是最外展 |
punchSnap/punchSettle)在新素材進來時會設回 1.0。
punchWindupSec 0.50 × 60fps)。這個值改了,動畫的階段切分要跟著改 —— 兩邊是同一個數字的兩種寫法。
3動畫要從文字手上接走這些資訊
動畫要從文字手上接走的資訊 —— 逐項
原型幾乎所有事件都是文字硬講的。如果新動畫只是把演出做漂亮、資訊仍然由文字在講,這批工只完成了一半。
| 現在用文字講 | 應該由什麼表達 | 驗收:遮住文字之後…… |
|---|---|---|
| 「對手在力竭 — 加壓!」 | 力竭的體態:肩膀起伏、護手垂下、重心變沉、腳步變重 | 看得出他累了、該壓上去 |
| 「破綻 — 擋不住」/「反擊!兩邊都開」 | 破綻姿勢(雙手張開上舉 + 軀幹後仰)+ 被彈開的位移 | 看得出他守不住了,而且兩邊都開 |
| 「這一拳被擋了」 | 架開/Parry 的動作 + 攻方重心被拉走 | 看得出是我剛剛那一拳造成的(因果,不只是「發生了什麼」) |
| 傷害數字大小 | 受擊的力度分級(一般/破綻中被打/連段命中) | 分得出剛剛那下重不重 |
| (現在完全沒有) 他要出手了、打哪邊 | 起手的蓄力形狀,左右可辨 | 看得出他要打了、打哪一邊 |
| (現在靠拳套姿勢) 他在守哪邊 | 防禦姿勢從正面一眼讀出左右 | 看得出他哪一邊是空的 |
⚠️ 驗的時候要從交接場景的 Eye_P1 相機看,不要用 Scene 視窗自由視角。
- 自己的體力/HP —— 第一人稱看不到自己的身體 → 拳套(體力見底下沉、雙防上遮、防禦時間到快速彈回)+ HUD 條
- 「我剛剛守錯邊」 —— 自己的失誤,身體表達不了 → 側邊條保留
- 無障礙冗餘 —— 色盲約占男性 8%;現場也可能聽不到音效 → 形狀/字級/震動幅度
📌 順序:先證明動畫讀得出來,再拿掉文字。文字應該退成備援,不是第一時間砍光。反過來做的話,動畫如果不夠讀,資訊就整個消失。
4場景 —— 全部新做
場景規格 —— 逐項
不沿用現有 JSG01 場景。下表原型值是尺寸參考,不是要照抄的樣子。
| # | 項目 | 原型值 | 說明 |
|---|---|---|---|
| 1 | 地板 | 9 × 9 m | |
| 2 | 背板 ×2(兩側) | 14 × 5 m,z = ±7 m | 給遠近參考 |
| 3 | 圍繩 ×3 + 角柱 | 高 0.55 / 0.97 / 1.39 m | z = ±2.6 m,中間那條是紅的。角柱高 1.8 m,x = ±3.4、z = ±2.6 m |
| 4 | 主光 ×2 + 頂補光 + 環境光 | — | 見下方對稱規約 |
| 兩人間距 / 眼睛高度 / FOV | 1.90 m / 1.55 m / 59° | 可調,但兩邊必須一致 |
驗收條件:把畫面左右對調,看起來要一樣亮。
JSG01/Sence/DualFist2P/ —— 打開 DualFist2P_Arena.unity 就是場地 + 兩個角色站在對戰位置 + 兩個第一人稱眼睛位置,不用按 Play(姿勢是烘進骨架的)。
DualFist2P_Arena.fbx 給你在別的軟體對尺寸;Materials/ 五個材質檔名帶顏色(Arena_Rope_D93340 就是那條紅圍繩)。
兩件看起來像 bug、其實不是的事:① 從 P1 相機看得到自己的身體(交接場景 layer 歸零了,實際遊戲會剔除)② 打光看起來很假(就是上面那條對稱規約)。
5打擊回饋 10 種
原型全是 IMGUI 純色貼片,全部重做。強度百分比是原型值,給你抓相對輕重。
下面九段是遊戲執行中直接錄的原型演出(這批保留 HUD 與第一人稱拳套,跟上面動畫清單那批相反)—— 特效是玩家的資訊管道,得連著 HUD 一起看。
我打中
攻方視角:暖白 13% 一閃+相機往前頂。手感要給攻擊者,不是只給挨打的人。
我挨打
挨打方視角:全螢幕紅 42%+大震+該側紅邊條+紅飄字(硬規則 ①)。
我擋下了
守方視角:藍白外框閃 85%+該側藍邊條+小震。跟「挨打」必須一眼分得出來。
我被擋
攻方視角:灰白 10%+相機往後彈+小灰字。不該演得像打中。
我架開對方
架開方視角:相機前頂+震,對手門戶大開、反擊窗開啟。
雙防
自己視角:暗角 22%,拳套本身實體擋住中央視野。
喘(力竭)
自己視角:全螢幕灰 30%(體力歸零)。
暈眩
只有對手看得到:頭上星星圈,掛在頭骨上跟著晃。
破綻中挨打
挨打方視角:紅閃壓到 40%(硬規則 ③),破綻提示仍讀得到。
(config 已列需求)
防禦自動放下
玩家必須看得見自己的防禦被強制放下(力竭、整個不能防禦時)。
打擊預告 新增
原本掛在 UI 規格(側邊條兩段式,DF-76)——起手前搖 0.32~0.5 秒該側邊緣淡黃描邊由弱到強脈動。forge 已驗證,2026-09-22 指派綠豆做正式特效表現,forge 那顆只是規格示意。
打擊回饋 10 種 —— 逐項規格11 項
| # | 事件 | 誰的視角 | 原型的表現 | 正式版重點 |
|---|---|---|---|---|
| 1 | 我打中 | 攻方 | 全螢幕暖白一閃(13%)+ 相機往前頂 | 攻擊的手感要給攻擊者,不是只給挨打的人 |
| 2 | 我挨打 | 挨打方 | 全螢幕紅(42%)+ 相機大震 + 該側紅邊條 + 大字紅飄字 | 邊條是關鍵,見硬規則 ① |
| 3 | 我擋下了 | 守方 | 藍白外框閃(85%)+ 該側藍邊條 + 小震 | 跟「挨打」必須一眼分得出來 |
| 4 | 我被擋 | 攻方 | 灰白一閃(10%)+ 相機往後彈 + 小灰字 | 成本在體力條上,畫面不該演得像打中 |
| 5 | 我架開對方 | 守方 | 相機往前頂 + 震 | 守方看不到自己的身體,受力感只能從相機來 |
| 6 | 雙防 | 自己 | 全螢幕暗角(22%) | 「看不到」要講得明白(拳套本身已實體擋住中央) |
| 7 | 力竭(體力歸零) | 自己 | 全螢幕灰(30%) | 🔴 刻意不用紅光 —— 紅光在遊戲語彙裡幾乎都是 power up |
| 8 | 暈眩 | 只有對手看得到 | 頭上星星圈 | 掛在頭骨上會跟著晃,那正是暈眩該有的樣子 |
| 9 | 破綻中挨打 | 挨打方 | 紅閃壓到 40% | 見硬規則 ③ |
| 10 | 防禦自動放下 | 自己 | ✅ 已定版 側邊條四態 + 警示三角形 | 動畫端要的是拳套垂下那一下;HUD 端見 UI 規格分頁 |
| + | 特效整合 | — | — | 美術表獨立列一項工時 |
三條硬規則
① 側邊條是玩家唯一的因果線索
挨打/擋下時要在該守的那一側畫一道邊條(紅=被打穿、藍=擋下了)。 沒有它,左右手的博弈在感官上不存在。
② 顏色不能是唯一訊號
紅綠色盲約占男性 8%。「擋下 vs 挨打」的差別必須同時體現在形狀(外框 vs 全屏)、字級(原型差 2 倍以上)、震動幅度上。
③ 回饋不能蓋掉它自己要傳達的資訊
破綻那 1.5 秒會被連打,每拳都把紅閃重設成滿 → 畫面全程 42% 紅,對手看不見,而那正是最需要看清楚的時候。解法是壓低不是關掉(降到 40%)。
6音效 10 支
音效 10 支 —— 逐支清單10 項
| # | 事件 | 需求 |
|---|---|---|
| 1 | 出拳起手 | 起手那一幀的預告音,左右要能聽辨(聲道 pan 或音色差) |
| 2 | 防禦自動放下 | 提示音(config 已留位 feedback.guardAutoDropSfx) |
| 3 | 打中 | 打在肉上,跟 #4 要能靠聽分辨 |
| 4 | 打在防禦上 | 被擋/擋下共用一支 —— 同一次撞擊只有一個聲音,視角差交給畫面 |
| 5 | 架開(parry) | 跟「打在防禦上」不能同音 —— 聽不出差別=破綻窗在聽覺上不存在 |
| 6 | 破綻中挨打 | ×2 傷害要加重版挨打音(對應視覺「壓到 40%」同一道理) |
| 7 | 力竭(體力歸零) | 喘氣 loop,狀態持續整段;也是對手「加壓」的聽覺提示 |
| 8 | 暈眩星星 | 只播一次、不 loop,跟星星出現同步 |
| 9 | 回合開始/結束 | 通用 Ready/Finish 音效位,沿用既有的、不用新做(ReadyFight.wav) |
| 10 | 勝負 stinger | 沿用既有勝利/Lose BGM |
- 對戰 BGM —— 沿用 JSG01 單人版既有關卡 BGM
- 擂台環境音(觀眾聲) —— 評估過不需要
- 倒數/勝負/UI 按鍵音 —— 全部沿用既有資源
Times up 頂替,KO 跟「時間到」是兩種收場。
⚠️ 另有基礎打擊音層(出拳風聲/揮空/受擊)沒列進上表 —— 揮空音是「我沒打到」的唯一聽覺線索。
7六條硬需求 —— 跟素材無關,重做也要滿足
硬需求 ①~④:root motion/第一三人稱兼顧/任意幀可打斷/破綻姿勢要真素材
① root motion 由動畫演
位移做進 clip 裡,RD 那邊把程式位移關掉。原型的量值給動畫抓幅度:被架開的一方往後彈 0.40 m、架開的一方往前壓 0.22 m。
repelDistance/counterLungeDistance 確實關了。② 每支 clip 要同時滿足第一人稱與第三人稱
第一人稱的手和第三人稱的身體是同一副骨架的兩層皮(靠 layer 分給誰看,不是兩份模型)。所以每支攻擊/防禦/待機,從「自己眼睛看出去」也必須成立:
- 兩隻手都要在頭的前方(原型男角待機那支就是敗在右手在頭後面,第一人稱看不到自己的右拳)
- 左右盡量對稱 —— 「讀得出哪隻手動了」是核心資訊,待機是它的參考基準
- 手不能穿模、拳頭要看得見
③ 任意幀可打斷 + 勝負強制切換
- 受擊動畫要能被「挨打之後才開始」的出拳或舉防打斷
- 勝負是切場事件:無淡入、強制切換(結算那一刻角色可能還停在防禦或出拳)
- ⚠️ mask 部分讓出行不通,試過兩次都被打槍 —— 接縫只會從「手/軀幹之間」搬到「軀幹/腿之間」
④ 破綻姿勢一定要真素材
「雙手張開上舉 + 軀幹後仰」,表達「被架開、門戶大開」。
教訓:缺姿勢就要素材,不要用程式湊。動作師編的姿勢是一個整體(肩、肘、腕、軀幹互相補償),用幾根骨頭逼近總有一個角度會露餡。
⑤ 最高優先 攻擊的起手要從對手的第一人稱讀得出來,左右分得出來
規則層留了 0.32 秒前搖給守方讀,但原型的起手從對手視角讀不出來,那 0.32 秒是空的。
| # | 要求 |
|---|---|
| 1 | 起手要有明確的蓄力形狀 —— 肩膀拉後/手縮回,讓對手看得到「他要出手了」 |
| 2 | 左手起手與右手起手要一眼分辨 —— 「猜左右」是這個玩法全部的博弈維度,讀不出邊等於沒有玩法 |
| 3 | 有效時間只有 0.32 秒,而且是從對手的第一人稱看(隔著擂台、對手佔畫面約 1/3)—— 細膩的手腕變化無效,要的是上半身輪廓層級的變化 |
| 4 | ⚠️ 前搖時間不能加長。掃描證實 >0.25s 雙防會失衡,0.32 已在懸崖邊。要加的是內容密度,不是時間 |
同一條線上另外兩件:HUD 側邊條兩段式(見 UI 規格分頁)、音效 起手預告音左右可聽辨。
硬需求 ⑥⑦:拳種要一眼分得出來/架開反擊是全身動作
⑥ 拳種動畫從第一人稱要一眼分得出來
2026-08-25 起優先度提高 拳種已改為 v1 就要做,所以這條從「正式版才要滿足」變成 v1 驗收項。
拳種帶傷害差(總跨度 ≤5%),而動畫是玩家驗證「系統認成什麼」的唯一管道。直拳/勾拳/上鉤拳從第一人稱看必須一眼分辨,不能只有細節差異 —— 否則玩家想打上鉤、被認成直拳,而且無法知道自己做錯還是系統認錯。
⑦ 架開/反擊是全身動作,兩隻手都要有軌道
MX_Parry 是純單手 clip —— 逐幀量過:右手動 0.925 m、左手只動 0.064 m。
引擎把手臂拆成左右兩層各自驅動,於是「沒有軌道的那隻手」就掉回待機的垂手,畫面變成軀幹在轉、一隻手在撥、另一隻手掛在旁邊不動。
| # | 要求 |
|---|---|
| 1 | 兩隻手都要有 key。不出力的那隻也要有支撐性的動作(跟著轉身走、留在防守位),不能整條軌道空著 |
| 2 | 另一隻手要往身體收(護著自己),不能跟著往外撥。兩手一起往外的版本當場被打槍 ——「我感覺不到反擊的幅度,另一隻手不要往外撥,而是要靠身體」。 幅度感來自不對稱,不來自把動作做大(動作做大反而會撞到硬需求 ⑤ 的 0.32 秒預告窗口) |
| 3 | 不要蓄力。撥開是對飛過來的拳做出的即時反應。代用素材前 30% 是往內收的蓄力,害得回報「我拳頭都揍下去、UI 都顯示了,0.5~1 秒後才播動畫」—— 那不是延遲,是素材自帶前搖 |
| 4 | 不要回程。播到最外展(撥開的那一刻)就結束,走完回程等於「手臂轉一圈」 |
| 5 | 左右各一支,理由:擋下那一側的軀幹朝向是相對那隻手編的 |
ArtRefs.CounterStartU / CounterEndU),就是為了砍掉上面第 3、4 條。
換成正式素材要把這兩個常數改回 0 / 1,否則會把新 clip 的頭尾各砍掉一段。
8交付規約
| 項目 | 規約 |
|---|---|
| 一個 FBX 多支 take | 一律指名 clip 名稱,不要「拿第一支」(第一支常常不是你要的那支) |
| 命名左右一致 | 左右後綴要成對,否則程式端只能一個一個猜 |
| 命名要能反映內容 | 名字與內容不符會選到錯的素材(原型拿到過握斧的手型) |
| 男女動作 | 共用一套。retarget 可互播,但姿勢可讀性要各自檢查 |
換素材後這些數值必須跟著重量
換素材要跟著重量的數值6 項
| 數值 | 綁在什麼上 |
|---|---|
OpeningHoldU/CounterStartU/CounterEndU | per-clip 關鍵幀比例,沿用會停在完全不相干的一幀 |
punchSnap/punchSettle/hitPlaySec | clip 長度。punchSnap/punchSettle 目標值已知 —— 設回 1.0(現在的 3.45/3.30 是補償借來素材用的) |
armX/armY/armZ/fovRef | 第一人稱 viewmodel 擺放,綁骨架 |
eyeForward/eyeUp/headFollow | 頭骨位置 |
repelDistance/counterLungeDistance | 世界空間距離,綁角色尺寸。root motion 由動畫演之後這組要關掉 |
fov | 「對手看起來多大」,對著現有模型調的 |
9其他美術交付
其他美術交付 —— 逐項4 項
| 項目 | 負責 | CP | 內容 |
|---|---|---|---|
| 角色服裝 1P/2P 隊色 | 品杰 | CP2 · 2W | 2P 藍色服裝要做,男女各一套。1P 服裝待美術決定(拿原本那套改色、或直接沿用不動 —— 兩種都可以,服裝顏色是用來「認出對面是誰」的,只要兩套彼此一眼分得出來就夠)。⚠️ 挑色時要在新擂台的打光下確認對比 |
| 第一人稱拳套 viewmodel | 品杰 | — | 三種狀態要看得出來:體力見底下沉/雙防上遮/防禦到期快速彈回。1P/2P 兩色(男女共用一套手部模型 → 兩色=2 套不是 4 套)。🔴 拳套與服裝必須共用同一組隊色色票 —— 兩者是不同時間做的,各自挑色一定對不起來 🆕 原型手臂佔位模型已備好(2026-09-30): FpArms_Male.fbx/FpArms_Female.fbx 已放進 Art repo 1.7_Boxing_2P 分支 JSG01/Character/Model/,RD 可先接。這是原型佔位、不是正式素材 —— 正式版仍是男女共用 1 套 × 兩色,做完取代這兩支 |
| 角色模型與蒙皮修正 | 未指派 | — | 頭盔與頭髮離開頭部的問題,要在 20 支動畫驗收前修 |
| 擂台場地 | Shyerlly | CP1 白模 CP2 背景/UV貼圖/烤光 | 見 §4 |
隊色色票
與選角公版的 1P 粉框/2P 藍框、隊色服裝同一組色票。
_Layout_JSG01 section(12 張 layout frame,19778:45)與
assets/render_2p_hud_states.py 產出的設計稿為準。
改圖改腳本再重跑,不要直接改 PNG。
1HUD 版位
左右分割,每人 960×1080
不是上下分割 —— 理由是人形比例。
兩半版面完全相同、不做鏡射
分割畫面是各看各的,兩邊一模一樣才公平。右半=左半全部座標 +960。
上=己方資源條、下=拳套活動空間
HUD 版位細節:資源條與拳套活動空間
對手資訊已整條拆掉。己方整組(頭貼+標籤+血量+體力+Fever)搬到頂端,底部完全清空讓給拳套。
HUD 逐元素版位與素材11 項
| 元件 | 位置(1P) | 尺寸 | 備註 |
|---|---|---|---|
| 自己頭貼 | x 20 / y 150 | 150×150 | 傾斜貼紙式,沿用 PlayerIcon/ 既有 8 張 |
| 自己隊色徽章 | x 90 / y 257 | 80×32 | 斜切小塊,內寫 1P/2P,疊在頭貼左下角 |
| 自己血量(粗・綠) | x 176 / y 202 | 756×48 | 頭貼右側。寬度/斜切角不動,純平移 |
| 自己體力(細・黃) | x 180 / y 260 | 748×22 | 血量下方,同上不 resize |
| Fever 倒數(僅 Fever 顯示) | x 188 / y 290 | 744×18 | 體力下方、新頂排最靠近中線的一條 |
| 計時(共用・跨分割線) | 中心 x 960 / y 12~132 | 242×120 | 三位數秒數,沒有底框。逐位拼 CountdownNums/0~9.png |
| 暫停鍵(共用) | x 1822 / y 18 | 78×80 | 一台手機只要一個。素材=pass.png |
| 連段 HIT(狀態層) | x 45 / x 196 · y 744~761 | 130×194 / 290×228 | 非常駐,見 §5 |
| 警示三角形(狀態層) | y 中心 530 1P x=225/745 | 332.16×288 | 非常駐,一手一顆,見 §3 |
| 側邊條 | 半螢幕左右緣 y 18~1102 | 22px 寬 | 滿版高度,見 §2 |
| 分割線 | y −11,高 1091 | 6px 寬 | 貼滿版高,一路貫穿到底 |
- 計時是素材不是文字 —— 逐位換
CountdownNums/0~9.png(315×469 等寬,描邊陰影都畫在圖裡)。RD 端不要接字型。 - 暫停鍵的素材叫
pass.png不是pause,節點叫Img_Setting—— 按名字搜尋一定找不到。 - 排版不能只看 bbox —— 計時器含描邊陰影的實際著墨是 x841~1078/y1~130,比 bbox 大。
兩套色彩系統 + 沿用的既有素材
兩套色彩系統,各管一件事
| 系統 | 色 | 管什麼 |
|---|---|---|
| 血條顏色 | 綠 | 自己(2P 已無對手血條) |
| 條的粗細 | 粗/細 | 類型:血量=勝負、體力=過程 |
| 頭貼徽章 + 拳套 | 1P 粉 #FC4F7A 2P 藍 | 身份,與選角公版、隊色服裝同一組色票 |
Bar/EnemyHp_*/Bar/EnemyStam_*,含 View_2P 的 _R 版本,6 張 layout frame 共 48 個節點全刪)。對方血量不是每拍都要看的核心資訊,但「這隻手不能防」「攻擊要來了」才是——空出來的位置改放 §3 警示三角形。沿用既有素材,美術零新增
沿用的既有素材清單4 項
| 元素 | 既有素材 | 呈現 |
|---|---|---|
| 血條外框 | PlayerLifeBarBox.png | 斜切多邊形。HP 外框由白改金(垂直漸層 #FFE9A8→#F5C34A→#D99B2A→#B8791E,weight 4);體力條維持白框 —— 金框是「這是主要資訊」的區別,不是全套統一 |
| 自己血量填充 | PlayerLifeBar.png | 綠→黃綠漸層+末端網點 |
| 體力填充 | FeverBar.png | 黃色+網點 |
| 頭貼 | PlayerIcon/ 既有 8 張 | 傾斜貼紙(白邊+陰影) |
Bar/JSG01_Track(槽:黑底+外框)/Bar/JSG01_Fill(填充:矩形 image fill + track 形狀遮罩)。
這樣 RD 改血量只改 Fill 那層寬度,斜角由遮罩保證,不會被 resize 拉變形。
⚠️ 不要用 resize 改 component instance 的長度(斜切角會被壓歪),等比縮放用 rescale()。
2側邊條兩段式(預告 + 結果)
既有側邊條從純「命中後反應」升級成兩段,共用同一塊版位,不是新元件。
forge 實機錄製
已驗證B 出左直拳(0.5s 前搖)→ A 這一側先淡黃描邊由弱到強 → 命中那一幀轉實心紅閃。
forge 實作參考:FirstPersonView.SyncTelegraph();鏡射公式沿用 FightRules.MirroredBlocking。
3力竭警示三角形
「防禦被強制放下、該手冷卻中不能舉起」這個狀態,新增紅色警示三角形 +「不能舉」文字提示。
forge 實機錄製
已驗證舉手撐滿 3 秒 → 強制放下、拳套垂下、三角形浮現 → 冷卻 0.5 秒結束、拳套舉回、三角形淡出。
警示三角形:三個觸發時刻與逐項規格
防禦自動放下是三個時刻,不是一個
| 態 | 側邊條表現 | 意思 |
|---|---|---|
| 舉防中 | 隊色條由上往下收縮 | 剩餘可舉時間 |
| 最後約 1 秒 | 轉琥珀 + 閃 | 快撐不住了。預警不用紅色(會跟被打穿的紅撞) |
| 強制放下 | 整條閃一下轉灰 + 拳套垂下 + 提示音 | 放下那一下 |
| 冷卻中 | 灰條由下往上回填 + 疊加警示三角形 | 最容易被誤判成偵測壞掉 —— 玩家會一直想舉卻舉不起來 |
消耗與回填方向相反是刻意的,一眼分得出在燒還是在恢復。雙防時兩側各跑各的。被打穿的紅、擋下的藍照原樣疊在同一條上短暫覆蓋。
三角形規格
警示三角形逐項規格5 項
| 數量/位置 | 一手一顆。y 中心 530,左右貼齊各自半版面 23%/77%:1P x=225/745,2P x=1185/1705 |
| 尺寸 | 332.16×288(原始未縮放 110.72×96 的 3 倍)—— 逐幀比對 GIF 實測校正過,不是估計值 |
| 層級 | 螢幕層,跟著相機,不隨拳套動畫抖動 |
| 時機 | 冷卻開始淡入、冷卻結束淡出 |
| 文字 chip | 「不能舉」,紅框深底,貼在三角形頂點正上方 10px,132×44。多國 ID 42036 |
| 與側邊條的關係 | 疊加不是取代 —— 側邊條講「還能撐多久」(連續資訊),三角形講「現在不能防了」(離散事件) |
符號沿用保齡球 JSG11 BW-125 的既有慣例。三角形會蓋到護頭帽上緣一部分,是預期效果。
isVisible 恆為 false,合成單一 mesh 才解決,代價是犧牲紅白對比。要做到參考圖效果得重新排查。
4破綻/力竭/Fever 狀態顯示
三者表達方式一致:外框發光 + 標籤 + 收縮倒數條。
| 狀態 | 表現 | 標在哪 |
|---|---|---|
| 破綻 | 外框金色發光 +「破綻 — 兩邊都能打」標籤 + 倒數條 | 狀態在誰身上就標在誰那排,不放畫面中央 |
| 力竭 | 體力條轉灰 + 拳套下沉 + 四周泛白 + 標籤 + 倒數條 | 自己那排 |
| Fever | 沿用單人雙拳那一套(見下) | 自己那半螢幕 |
三條倒數條
三條的做法一樣:一個深色的槽 + 一條會從右往左縮短的填充。顏色各自不同,讓玩家一眼分得出現在是哪個狀態。
| 狀態 | 顏色 | 位置 | 素材 |
|---|---|---|---|
| 破綻 | 亮黃 | 破綻標籤正下方 | HUD2P/ThinTrack_Opening.png(槽)+ OpeningCountdownBar.png(填充) |
| 力竭 | 冷白 | 力竭標籤正下方 | HUD2P/ThinTrack_Winded.png(槽)+ WindedCountdownBar.png(填充) |
| Fever | 紅→橘→黃 | 自己資源條那一排,最靠近畫面中線 | HUD2P/ThinTrack_Fever.png(槽)+ FeverCountdownBar.png(填充) |
Fever = 沿用單人雙拳既有設計,美術零新增
Fever 沿用素材清單4 項
| 層 | 內容 | 素材 |
|---|---|---|
| 背景 | 場景 Hide → 藍色 wave shader 背景,只留人物 | RD 端既有 shader |
| 拳套 | 雙手拳頭冒火(單手無火,同單人版規則) | JSG01/FirePuch/FireGlove_Particles.prefab + FireGlove.mat |
| 字幕 | 「FEVER TIME」 | JSG01/UI/fever.png |
| 倒數 | 一條細橘條,新頂排最靠近中線(體力條下方) | HUD2P/ThinTrack_Fever.png + FeverCountdownBar.png(2026-09-16 交付) |
5連段 HIT
連段是三級傷害加成,KO 來自「連讀對幾次」—— 它是這款遊戲最該被看見的即時回饋。
| 元件 | 位置 | 尺寸 | 素材 |
|---|---|---|---|
| 連段數字 | x 45 / y 761 | 194×130 | JSG01/UI/comble/0~9.png(341×515,紅字黑描邊) |
HIT! 貼紙 | x 196 / y 744 | 290×228 | JSG01/UI/comble/Comble Hit.png(626×472) |
連段 HIT 三級的用色與光暈規格
三級用色相 + 光暈表達,不換素材
| 級 | 數字 | 貼紙 |
|---|---|---|
| 1 | 原色紅 | 原色 |
| 2 | 橘(紅→金中間值) | 原色 + 弱光暈 |
| 3 | 金黃(色相 +27°、提亮 18%) | 同色相偏移 + 金色外光暈(高斯 20px 疊 5 層) |
數字不做 component:逐位換圖,等級色由數字圖自己帶。
6開場/收場演出
🆕 收場 DOTween 動態 —— 字卡+鏡頭層(2026-09-11 定案)
角色本身仍是「無淡入、強制切換」(停在當下姿勢,不做倒地/勝利過渡動畫,見下方逐段規格的硬需求)—— 這裡新增的是另一層:字卡+鏡頭的 DOTween 動態,不碰角色骨架,所以不會撞回 mask 分部位過渡失敗的老問題。
rescale()/rotation 做出真正的 2.6x/-8° 姿勢再截圖,不是軟體疊圖猜的。三顆新 frame(Ending_KO_Anim_00_HitStop/Ending_KO_Anim_01_PunchIn/Ending_TimeUp_Anim_00_SlideStart)已經用 Smart Animate 接好 AFTER_TIMEOUT 自動播放,Figma Present 模式可以直接看到接近正式節奏的版本,細節見 references/figma-map.md 對應條目。
K.O. / TIME UP 完整時間軸表2 表
K.O.(份量最重)
| 時間 | 動作 |
|---|---|
| t=0.00s | 判定成立 → 無淡入硬切到收場鏡頭 |
| t=0.00~0.12s | Hit-Stop:Time.timeScale 壓到 ~0.05(非真 0,避免動畫卡死一幀)+ 全螢幕白閃 DOFade 0→45%→0 |
| t=0.00s | SFX:🆕 KO_Impact.wav(新做)跟白閃同幀觸發 |
| t=0.12~0.42s | 字卡衝入:DOScale 2.6→1.0 Ease.OutBack(overshoot 落在 t≈0.24s)+ DORotate -8°→0°+ DOShakePosition(strength 24px/vibrato 20,衰減 0.30s 跟字卡同時收) |
| t=0.12s | SFX:字卡 whoosh(沿用既有音效庫任一支即可,不用新做) |
| t=0.42s+ | 定格 → 交給結算頁淡入(另一條 tween,不在本節範圍) |
TIME UP(份量刻意較輕)
| 時間 | 動作 |
|---|---|
| t=0.00s | 計時歸零 → 硬切,沒有 Hit-Stop、沒有白閃、沒有震動 |
| t=0.00s | SFX:既有 TimesUp.wav(沿用,不用新做) |
| t=0.00~0.35s | 字卡掃入:DOAnchorPosX 畫面右外 +900 → 置中,Ease.OutCubic,不縮放不旋轉 |
| t=0.35s+ | 定格 |
兩種收場的份量差,全部濃縮在「有沒有 Hit-Stop/白閃/震動」這三件事上——成本很低,都是程式面的 tween,不用等新動畫。完整規格與內部 keyframe 對照見 dual-fist-checklist.md DF-80。
開場/收場演出 —— 逐段規格
序列:READY → FIGHT!!(一顆 VFX 播完)→(對戰)→ K.O. 或 TIME UP
VFX/_Assets/Jsg_/ 而不是 JSG01/UI/)。
🔴 CountdownNums/ 不是開場倒數 —— 它是 HUD 那個三位數計時器取 Sprite 用的。
// 2P 照單人版做,只是沒有 Boss 入場那一段 GameStartTransitions() → GamePause=true → GameStartCam(1s) 運鏡 └─ StartAnimationCGSwitch(true) // 開 CG_StartAnimation PlayVFXMusic(ConstReadyFight=131) // 音效 ReadyFight.wav _vfxJSG1UIReady.Play() // ParticleSystem「VFX_JSG1_UI_Ready」 await (VFX main.duration) // 時長由 VFX 自己決定,不寫死秒數 AllUIShowSet(true) / GamePause=false StageCountDown() // 關卡計時開始
開場/收場字卡規格 —— 逐張
字卡:只剩兩張要出
| 字卡 | 來源 | 要做的事 |
|---|---|---|
| READY | ✅ 既有 jsg_Ready.png 第 2 組(橘黃,真去背) | 零工項 直接沿用單人版實機那張 |
| FIGHT!! | ✅ 既有 jsg_Ready.png 第 3 組 | 零工項 取代原本規劃的 GO |
| TIME UP | 字形取自 jsg3_word.png(真去背) | 拆掉木牌邊框、字形留用重上色 |
| K.O. | 無現成 | 重畫。份量處理參考 Comble Hit.png |
❌ GO 字卡取消 —— 既有開場字組就是 READY → FIGHT!!,不需要再多一張。風格以 fever.png 那套橘黃金屬漸層+黑描邊斜體為準。
| 項目 | 規格 |
|---|---|
| 字幕行為 | 掃過即消,HUD 全程在、不做黑幕 |
| 收場 | 切場事件:無淡入、強制切換 |
| 開場音 | 既有 ReadyFight.wav,不新做 |
| 收場音 | TIME UP 用既有 TimesUp.wav;KO 音要新做 |
🔴 兩張是同一個 RectTransform 換 sprite —— 出圖必須統一畫布置中,否則實機會跳位。
2P 比單人更需要這幾張:兩個人共用一台手機,開打時機要同時被兩個人讀到,只有音效在吵雜環境(現場、賣場)會漏。
7結算頁
版型與素材=沿用 1P 單人結算,美術零新增。暫停彈窗掛平台公版不做客製。
結算頁逐元素版位6 項
| 元素 | 沿用的既有素材 | 規格 |
|---|---|---|
| 背景 | SettlePage/WINBottom.png(敗方 LOSEBottom.png) | 1920×1080 全螢幕底圖 |
| 勝負字 | SettlePage/WIN.png(敗方 LOSE.png) | x 546/y 18,828×271 |
| 分數列 | SettlePage/TotalScoreField.png | x 440/y 396,1200×56 |
| 其餘三列 | SettlePage/SettleField.png | 1200×48,列距 92 |
| 勝方頭貼 | PlayerIcon/ 既有 8 張 | 300×300,x 112/y 404,位置固定不鏡射 |
| 多國碼 | 既有 41035 / 41036 | 1P/2P 分數 |
結算頁 2P 專屬處理與按鈕列
2P 專屬的只有三件
- 雙欄對比 —— 同一條上左 1P 右 2P,用隊色字分
- 勝方頭貼在左、換隊色 variant
- 收場方式徽章(K.O./TIME UP)掛在勝負字下
2P 不鏡射(RD 只有一套 layout):2P 勝時只換 ①勝負字下的隊色徽章 ②勝方頭貼 ③數值左右對調。
按鈕列
| 主列三顆置中 | 回藍牙列表 / 再次挑戰 / ✅ 換角色 |
| 右上角 | 留空 —— 原本規劃的分享鈕已於 2026-09-01 取消(社群產品 Jcommunity 停止),不用做;主列三顆不受影響 |
第三顆鈕定案「換角色」:雙人公版原文案是「選擇其他關卡」,但 2P 雙拳沒有關卡;角色選擇(外觀,不影響能力值)是本模式對應的等價維度。 JSG12 遇過同一問題改成「重新選卡」,但雙拳沒有卡牌概念,不採用。
❌ highscore.png / NewRecord.png 不用 —— 2P 不進排行,不顯示最高分徽章。
8四手環連線頁
四手環連線頁 —— 逐項規格
選裝置沿用現有藍牙掃描面板,面板行為不改,只在標題帶上槽位名。
連線頁逐項規格6 項
| 項目 | 規格 |
|---|---|
| 版面 | 左右分人(左欄 1P/右欄 2P,左右要跟遊戲內分割畫面一致)、欄內上下堆裝置(左手在上、右手在下,兩欄順序相同不鏡射)。日後加裝置就是該欄多一列 |
| 面板標題 | 帶槽位名,例:「選擇 1P 左手的裝置」。多國 ID 41055~41058 |
| 每列三態 | 未指派(虛線+「點此選擇裝置」)/已連線/已指派但未連線(裝置名還在、圖淡化、顯示「未連線」) |
| 沒有「重新連線中」狀態 | 重連是玩家點該格、打開藍牙面板才執行。掉線的那一格只會退回「未連線」,其他三格不受影響 |
| 裝置綁定記憶 | MAC→槽位,下次進來自動連線帶入。四格全就緒開始鈕才亮 |
| 連線方式 | 四裝置採一隻一隻連 |
- 面板每行顯示尾碼 + 訊號強度 —— 尾碼只負責「四行不會混、不會重複指派」,不是辨識
- 真正的辨識動作=把要指定的手環靠近手機,訊號最強排最上
- 操作指引:一次只戴/開一隻,列表新出現的那隻就是它 —— 不需要程式支援
1入口與觸發
入口與觸發逐項規格5 項
| 項目 | 規格 |
|---|---|
| 入口 | 教學鈕 → 教學彈窗(平台公版 T_Tutorial),內容由 per-game manifest 載入 |
| 單/雙人切換 | 彈窗右緣外側垂直堆疊的懸浮標籤頁(x1650/y240 起,標籤寬 200)。不放頂部(會壓到玩家名/UID) |
| 標籤文字 | 中文「單人教學」/「雙人教學」,英文 1P/2P。多國 41053/41054⚠️ 英文別用 Solo Mode/Versus Tutorial 這種後綴 —— 164~235px,可用寬只有 144 |
| 教學鍵不上鎖 | 不做「首次自動彈出」那套 —— 通則的「有歷史最高分就不自動顯示」在 2P 沒分數也沒紀錄、用不了。改成玩家自己挑,現場一直換小孩也不會漏掉入口 |
| 單人 5 頁不動 | 那組 icon 對單人是正確的,沿用既有影片 |
2雙人教學影片 7 支
所以問題不是「icon 長得不一樣」,而是它指向一套 2P 不存在的東西: 玩家看完影片,在 2P 畫面上永遠找不到影片教他看的那顆東西,還會以為自己漏了什麼機制。
抽幀確認 5 支:防禦藍盾/雙防左右兩顆/直拳黃色六角/鉤拳綠色六角+橫向雙箭頭/上鉤拳紅色六角+向上雙箭頭。
✅ 留著不用重做
動作展示那一層 —— 左半的人物動作演示沿用既有素材。
🔴 要換掉
右半 —— 把那組單人玩法提示 icon 拿掉,改成實際 2P 遊玩畫面。
7 支一律「動作展示 + 實際遊玩畫面」雙層對照,讓玩家看到「我做這個動作 → 遊戲裡會變成這樣」。
7 頁清單
7 頁教學影片清單7 項
| # | 標題 | 說明文字 | 多國 ID |
|---|---|---|---|
| 1 | 直拳 | 雙腳前後站,後手手背朝上快速出拳 | 42010_42011 |
| 2 | 左/右鉤拳 | 手臂與肩膀平行,手背朝上快速出拳 | 42012_42013 |
| 3 | 上鉤拳 | 由下往上瞄準對手的下巴出拳 | 42014_42015 |
| 4 | 舉手防禦 | 舉起左手或右手並維持住,能擋下同一側打來的拳 | 42026_42027 |
| 5 | 雙手防禦 | 雙手同時舉起可擋住兩側攻擊,但會擋住視野、且不回體力 | 42028_42029 |
| 6 | 反擊 | 單手擋下後對手會露出破綻,趁機馬上打回去,傷害加倍 | 42032_42033 |
| 7 | 力竭 | 體力歸零會力竭:出拳變慢、傷害減半,而且無法防禦 | 42034_42035 |
🔴 2026-08-25 重排(DEC-JSG01-025):三個拳種頁併到最前面(直拳/鉤拳/上鉤拳),
而且三頁全部沿用既有多國 ID —— 第 1 頁改用直拳的 42010_42011,
文案風格因此跟後兩頁一致(都是純動作描述)。動作展示層同樣沿用
(Jab_Straight/Hook_Left_Right/Uppercut_Left_Right)。
❌ 原第 4 頁「擋對邊」刪除 —— 它跟第 4 頁「舉手防禦」的「能擋下同一側打來的拳」是同一句話換句話說,
多一頁只換來一次翻頁。新拍支數因此從 3 支降為 2 支(W-02 反擊/W-03 力竭)。
⚠️ 兩組多國作廢要從 xlsx 撤掉:42024_42025(原「出拳」)與
42030_42031(原「擋對邊」)。其餘紅底新增待翻譯。
🔴 缺口:42011 是純動作描述,沒有 2P 特有的「同一隻手揮完要先收回才能再出下一拳」
(出拳冷卻),改用既有 ID 之後這條規則在教學裡沒有地方講 —— CP1 觀察玩家會不會自己發現。
風格:7 支全走 3D 角色動畫
| 畫風 | 跟既有 V-01~V-05 同一種(賴神整理動畫 → Shyerlly 渲染)。不用真人實拍 —— 同一個 tab 裡翻頁,前幾頁動畫、後幾頁真人,玩家會以為在看兩件事 |
| 兩人同時入鏡 | 用 3D 排演兩個角色同框。刪掉「擋對邊」之後,真正需要同框的只剩第 6 頁反擊(擋完打回去) |
3實作:2P 專用 prefab 是唯一解
實作:2P 專用 prefab 與位址規則
videoboxingtutorial,清單=該 prefab 上 ReferenceCollector 的 key,格式 {標題多國ID}_{說明多國ID}。
同一款遊戲拿到的永遠是同一份清單 —— 所以不能直接改現有 prefab 的 key,會把已上線的單人教學一起改壞。
| 要做的事 | 內容 |
|---|---|
| 另建 2P 專用 prefab | videoboxing2ptutorial + 位址加教學類型後綴。單人那份一個字都不動 |
| 掛 7 個 key | 42010_42011 / 42012_42013 / 42014_42015(三個拳種頁沿用既有)/ 42026_42027 / 42028_42029 / 42032_42033 / 42034_42035 |
| 教學提示補一句 | 「手舉太久會自動放下」—— 玩家一定會遇到防禦強制放下 |
⚠️ 既有單人版 asset 檔名是 Bundles/Video/videoboxingtutoria.prefab(少一個 l),但 Addressable address 正確所以功能無誤 —— 不要「順手修好」。
1功能統計(DF-36 ~ DF-96)
2原型驗證分佈
✅ 原型已驗=實測過有數字|⚠️ 部分驗=會動但關鍵指標沒量到|❌ 原型沒有=這一層原型完全不存在
✅ 已驗的核心(16 項)
擋下判定、防禦分邊、體力經濟、空防懲罰、擋到回復上限、防禦上限與冷卻、雙防代價、力竭、Fever、連段、勝負判定、舉防姿勢偵測、左右分割雙第一人稱、第一人稱 viewmodel、動畫層接縫參數、全螢幕回饋自動減弱
⚠️ 部分驗(5 項)
揮拳偵測(門檻數字不能直接搬 —— 原型算標量、正式版算向量,單位不同)、破綻窗口(會觸發但真人反擊率沒量)、側邊條回饋、破綻/力竭/Fever HUD、手環校正流程(原型是鷹架)
3技術風險
技術風險 —— 逐項與緩解方式
| 配置 | 每條連線負擔 | 結果 |
|---|---|---|
| 1 台裝置開 2 通道 × 2 台 | 208 包/秒 | 爆過 過去會爆掉的是這個 |
| 4 台裝置各 1 通道(雙拳 2P 要的) | 104 包/秒 | 既有量測不掉包,但沒測過完整情境 |
| 項目 | 內容 |
|---|---|
| 驗收判準四條連動 | 掉包率/延遲/封包間隔 p95/不要為了省頻寬把 gyro 加回來 |
| 要訂機型下限 | 既有量測顯示低階機(A25)在 9m 會有其中一台掉包、高階機(v50)一直正常。只拿高階機測會過不了關也不知道 |
| 時機 | 要在 CP1 那場之前做完 —— 壓測沒過的話掉包會污染 CP1 量到的所有數據 |
| 兩段式門檻 | 0.15g 開始採樣 / 0.30g 才算一拳。不是選配 —— 原型 punchThresholdG 的可用餘裕只有 0.5 g(雜訊實測上限 2.9 vs 門檻 4.0),單段門檻在四台環境下守不住 |
| 感測門檻不能換算 | 原型的門檻/校正/凍結式重力是鷹架,不進正式版 —— 正式版統合 Andros(origin/2.4)。拿原型的 punchThresholdG 去填 Andros 的門檻,會得到一個完全不相干的靈敏度 |
Clamp(前搖, 0, 收拳 × 0.8) —— 只拉前搖不拉收拳會被靜靜夾住。
前搖從 0.32 拉到 0.50 只是把空窗變大了,不是把資訊變多了。
4移植與交接
移植與交接 —— 要做的事逐項
research 分支是工作場地,不是合併來源research/JSG01_DualFist2P 是從 master 切的,而 origin/2.4 跟 master 沒有共同祖先 ——
所以它永遠 merge 不過去,只能手抄。把它當成「可執行的規格書」,不要當成「等著被 merge 的 feature branch」。
| 要做的事 | 內容 |
|---|---|
| 四裝置移植正式環境 | 🔴 不在任何一張甘特圖上,而所有玩法開發都排在它後面。原型的 BLE→bridge→UDP 全是鷹架,正式版走 Andros |
規則層手抄 + 建 FightConfigAsset | C# 類別已在,資產檔至今沒建。建立方式=用 ImportFromJson() 從
Config/fight-config-prototype-snapshot.json 灌入初值,灌完之後權威在這份 SO,JSON 變成死的參考檔。欄位與值見「核心玩法 §9」 |
| root motion 打開 + 程式位移關閉 | 兩邊都演會疊成兩倍 —— 開 root motion 時要確認 repelDistance/counterLungeDistance 確實關了 |
| 換素材後重量 per-clip 常數 | OpeningHoldU/CounterStartU/CounterEndU 沿用會停在不相干的一幀;punchSnap/punchSettle 設回 1.0 |
| 刪除兩個死參數 | block.opponentStaminaDrain(方向相反)與 block.windowMs(會被實作成時機窗口) |
| 反擊率量測輸出 | 一局結束印一行 log,前綴固定 [JSG01-2P][RoundEnd] 方便 grep。見下方 CP1 |
research/JSG01_DualFist2P(最新 ebedd5c8)已對齊 2026-08-25 定版:
減傷 0.25/0.60、接回空防倍率 3.0、平衡測試 baseline 用新實測值重訂、
新增 Tests/config-audit.py(四處數值交叉稽核)。
📌 那包的 README 就是操作手冊 —— 三個已知陷阱、怎麼建 SO、怎麼跑測試、七項判準怎麼看,
都寫在裡面,這裡不重述。逐次改了什麼看 git log 與 KB decisions.md。
Jacfitness_Art submodule 的 feat/jsg01-dualfist-2p-arena-handoff 分支。
動畫師覆蓋 20 支佔位檔之前,要先確認他拿到的是這條分支 —— 在主線上找不到佔位檔會以為東西不見了。
5CP1 驗收 —— 三項綁在同一場
CP1 驗收 —— 三項的完整量測方式
| 測試 | 做法 | 判準 |
|---|---|---|
| A · 遮字測試 | 錄一局後製把所有文字遮掉(保留血條長度/側邊條/方向線/回饋特效),找沒參與那局的人答四題:誰快輸了/剛那拳是打中還被擋/對方下一拳打哪邊/誰在破綻; 再加問「左半邊是哪一位玩家」(那題只剩隊色能答) |
動畫接手資訊的唯一驗收法。⚠️ 要從 Eye_P1 相機看,不要用 Scene 視窗自由視角 |
| B · 反擊率量測 | 一局結束印:局長秒數/收場方式/勝方/P1 與 P2 各自的「打出破綻次數 N」「破綻中挨拳數 M」「反擊率 M/N」/攻守易位次數/當下的 hpMax 與每拳傷害值 |
⚠️ 比值請程式算好印出來,不要只印 N 和 M。 ⚠️ 必須分邊印 —— 兩邊合起來平均會把「高手打新手」洗掉 ⚠️ 一定要帶 hpMax 與傷害值 —— 當天會改值再打,log 沒帶參數事後分不清哪局用哪個設定 |
C · 真人局長重訂 hpMax |
用現值打 4 局取局長中位數 T,新 hpMax = 185 × 75 ÷ T,當場填進 FightConfigAsset 再打 2 局驗證落回 60~90 秒 |
🔴 現值照 bot 掃描訂,而「bot 秒數→真人秒數」的換算已實測失效。不要帶著算式離開現場。 ⚠️ 改完必須重跑掃描 |
能同時寫一份 csv 到裝置上更好(事後從 console 撈很痛)。
6待確認彙總
已拍板的不列在這裡(見各分頁)。以下 12 項仍開放。
🎨 待美術回覆(4)
待美術回覆的項目4 項
| # | 問題 | 對象 | 卡住什麼 |
|---|---|---|---|
| 1 | 新場地的規模與風格 | Shyerlly + TM | 場地開工 |
| 2 | 圍繩以外的深度線索方案(地板紋理/觀眾席…) | Shyerlly | 同上 |
| 3 | 角色蒙皮修正與第一人稱拳套素材誰做 —— 目前兩項都沒指派 | 賴神 | 蒙皮要在 20 支動畫驗收前修 |
| 4 | 1P 服裝拿原本那套改色、還是直接沿用不動(2P 藍色已確定要做) | 賴神 + 品杰 | 不擋,兩種都可以 |
🔊 待音效(1)
| # | 問題 | 對象 | 現況 |
|---|---|---|---|
| 5 | 音效三件的內容(起手預告/防禦自動放下/打中-被擋-擋下可聽辨)—— 特別是起手預告音左右可聽辨做不做得到 | 鏡 | 排程已排(CP2、10 支各 1W),內容未定 |
🧪 待 CP1 驗證(4)
待 CP1 驗證的項目4 項
| # | 問題 | 怎麼收 |
|---|---|---|
| 6 | 🔴 四台同時 BLE 壓測 —— 唯一硬風險 | 要在 CP1 那場之前做完,否則掉包會污染所有數據 |
| 7 | hpMax 沒有真人依據 | CP1 測試 C |
| 8 | 破綻迴圈的真人反擊率(只有影片佐證) | CP1 測試 B |
| 9 | doubleGuardEmptyPenaltyMultiplier 被誤刪,已接回。見 §9 與 KB DEC-JSG01-023 |
⚙️ 待 RD(2)
| # | 問題 | 影響 |
|---|---|---|
| 10 | 警示三角形的驚嘆號跟三角形同色 —— 拆兩個 renderer 時 MeshRenderer.isVisible 恆為 false,根因未查到 | 視覺打折(犧牲紅白對比),不擋功能 |
| 11 | 「手環 ↔ 側別」的映射在遊戲層還是連線層?附帶:遊戲中發現戴反能不能中途對調 | 不擋 v1 —— 只影響 v2 要不要把左右對調鈕加回來 |
🎬 待動畫完成後實測(1)
| # | 問題 | 時機 |
|---|---|---|
| 12 | 拳種的第一人稱可辨識度(硬需求 ⑥)—— 直拳/勾拳/上鉤拳從第一人稱看要一眼分辨 | 20 支動畫做完才能測 |
📋 完整功能表
feature-checklist.md) → HTML 自動同步生成。
一. 核心攻擊系統 (6 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-01 | 直拳攻擊判定 | ⬜ | 🔧 | ⬜ | 動畫 3 取 1 random |
| F-02 | 上鉤拳攻擊判定 | ⬜ | 🔧 | ⬜ | — |
| F-03 | 右鉤拳攻擊判定 | ⬜ | 🔧 | ⬜ | — |
| F-04 | ~~備戰模式~~ | ⬜ | ❌ 已移除 | ⬜ | 現只有一般待機 |
| F-05 | ~~每拳冷卻間隔~~ | ⬜ | ❌ 已移除 | ⬜ | 無冷卻,揮就算一拳 |
| F-06 | 攻擊 2D UI 提示 + 音效 + 特效 | ⬜ | 🔧 | ⬜ | — |
二. 弱點系統 (3 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-07 | Boss 弱點拳種顯示 | ⬜ | 🔧 | ⬜ | — |
| F-08 | **每揮一拳更新弱點顯示** | ⬜ | 📋 | ⬜ | 2026/02/25 決議;原為固定拳數更換 |
| F-09 | 弱點命中威力加成 + 特殊音效特效 | ⬜ | 🔧 | ⬜ | — |
三. Combo & Fever 系統 (6 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-10 | Hit Combo 累積 + 分數/Fever 加成 | ⬜ | 🔧 | ⬜ | 受傷/暈眩時中斷 |
| F-11 | Fever 條累積(Boss 攻擊時不累積) | ⬜ | 🔧 | ⬜ | UI 暗示不可累積 |
| F-12 | Fever 連擊模式觸發 | ⬜ | 🔧 | ⬜ | 插入形式 |
| F-13 | Fever 場景切換(Hide 場景 + Shader 背景) | ⬜ | 🔧 | ⬜ | — |
| F-14 | Fever 連擊傷害(固定,越多拳越痛) | ⬜ | 🔧 | ⬜ | — |
| F-15 | Fever 順延 Boss 攻擊 | ⬜ | 🔧 | ⬜ | Boss 攻擊中觸發→結束後進入 |
四. 防禦 QTE 系統 (4 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-16 | Boss 固定秒數攻擊觸發 | ⬜ | 🔧 | ⬜ | 驚嘆號 UI 前置 1 秒 |
| F-17 | 縮圈 QTE 動畫 + 檢查點 | ⬜ | 🔧 | ⬜ | 正防/側防 |
| F-18 | 防禦成功:盾牌 icon + 不損血 + Combo+1 | ⬜ | 🔧 | ⬜ | — |
| F-19 | 防禦失敗:打叉 icon + 損血 + Combo 斷 | ⬜ | 🔧 | ⬜ | — |
五. Boss AI & 攻擊 (5 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-20 | Boss 普通攻擊(3 種動畫 random) | ⬜ | 🔧 | ⬜ | 3~10 秒動畫 |
| F-21 | Boss 特殊攻擊(血量門檻觸發) | ⬜ | 🔧 | ⬜ | 傷害 2 倍 |
| F-22 | Boss Cut in UI(特殊攻擊前 1.5 秒) | ⬜ | 🔧 | ⬜ | 此時攻擊無效 |
| F-23 | Boss 死亡動畫特寫 + 強制轉場 | ⬜ | 🔧 | ⬜ | 即使攻擊中也強制 |
| F-24 | Boss 攻擊動畫防禦關鍵幀配置 | ⬜ | 🔧 | ⬜ | RD 手動拉 + 動畫組指定 |
六. 計分與結算 (5 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-25 | 分數計算(關卡分+總傷害+Combo+時間+血量) | ⬜ | 🔧 | ⬜ | — |
| F-26 | 勝利結算畫面(3D 特寫 + UI) | ⬜ | 🔧 | ⬜ | — |
| F-27 | 失敗結算畫面 | ⬜ | 🔧 | ⬜ | — |
| F-28 | 歷史最高分圖示 | ⬜ | 🔧 | ⬜ | — |
| F-29 | 勝利/失敗鏡頭運鏡 | ⬜ | 🔧 | ⬜ | — |
七. 關卡系統 (7 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-30 | 一般模式:單關 Boss 選擇 | ⬜ | 🔧 | ⬜ | — |
| F-31 | 闘關模式:5 關串接 + Combo 延續 | ⬜ | 🔧 | ⬜ | — |
| F-32 | 闘關轉場(不跳結算直接換場) | ⬜ | 🔧 | ⬜ | Loading 條 |
| F-33 | 闘關總分加總 + 排行 | ⬜ | 🔧 | ⬜ | — |
| F-34 | Boss 難度差異(血量/攻擊力/攻擊規律/時間) | ⬜ | 🔧 | ⬜ | 企劃表控制 |
| F-35 | Boss 進場動畫 | ⬜ | ⏸️ | ⬜ | 「有時間再做」 |
| F-36 | 闘關抽選機制(企劃表控制 2 取 1) | ⬜ | 📋 | ⬜ | 未來加入隨機 |
八. UI 元件 (10 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-37 | Boss 血條 + 頭像 | ⬜ | 🔧 | ⬜ | — |
| F-38 | 遊戲倒數計時 | ⬜ | 🔧 | ⬜ | — |
| F-39 | Combo / Hit 顯示 | ⬜ | 🔧 | ⬜ | — |
| F-40 | 玩家頭像 + 血條 + Fever 條 | ⬜ | 🔧 | ⬜ | — |
| F-41 | 弱點提示 UI | ⬜ | 🔧 | ⬜ | — |
| F-42 | 驚嘆號 UI | ⬜ | 🔧 | ⬜ | — |
| F-43 | 縮圈 QTE UI(正防/側防) | ⬜ | 🔧 | ⬜ | — |
| F-44 | Ready / GO 動畫 | ⬜ | 🔧 | ⬜ | — |
| F-45 | Times up / Victory / Lose 特效 | ⬜ | 🔧 | ⬜ | — |
| F-46 | 結算畫面 UI | ⬜ | 🔧 | ⬜ | — |
九. 非遊戲畫面 (7 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-47 | 主選單(PLAY/教學/排行/設定) | ⬜ | 🔧 | ⬜ | — |
| F-48 | 未連藍牙浮水印提醒 | ⬜ | 🔧 | ⬜ | — |
| F-49 | 模式選擇(一般/闘關) | ⬜ | 🔧 | ⬜ | — |
| F-50 | 關卡選擇(Boss 頭貼/名稱/難度) | ⬜ | 🔧 | ⬜ | — |
| F-51 | 角色選擇(男/女) | ⬜ | 🔧 | ⬜ | 特殊角色暫不開放 |
| F-52 | 教學頁面(翻頁式) | ⬜ | 🔧 | ⬜ | — |
| F-53 | 設定/暫停/排行/藍牙(共用模組) | ⬜ | 🔧 | ⬜ | — |
十. 鏡頭 & 轉場 (4 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-54 | Boss 入場運鏡 | ⬜ | 🔧 | ⬜ | — |
| F-55 | 勝利運鏡(Boss 特寫 → 玩家) | ⬜ | 🔧 | ⬜ | — |
| F-56 | 失敗運鏡 | ⬜ | 🔧 | ⬜ | — |
| F-57 | 闘關轉場運鏡 | ⬜ | 🔧 | ⬜ | — |
十一. 音效 (8 項)
| # | 模組 | 功能 | 負責 | 狀態 | 備註 |
|---|---|---|---|---|---|
| F-58 | 關卡 BGM(每關不同) | ⬜ | 📋 | ⬜ | — |
| F-59 | Fever BGM | ⬜ | 📋 | ⬜ | — |
| F-60 | 拳擊音效(3 拳種 + 弱點/普通) | ⬜ | 📋 | ⬜ | — |
| F-61 | 防禦判定音(成功/失敗) | ⬜ | 📋 | ⬜ | — |
| F-62 | Ready/Go/Times up/CutIn/勝利/失敗 音效 | ⬜ | 📋 | ⬜ | — |
| F-63 | Fever 單拳音效(3 個 random) | ⬜ | 📋 | ⬜ | — |
| F-64 | Boss 動畫特效音 | ⬜ | 📋 | ⬜ | — |
| F-65 | 點擊音 | ⬜ | 📋 | ⬜ | — |
JSG01 雙拳 2P — 完整企劃書 · v1.0 · 2026-08-25
SSoT:games/JSG01-boxing/(mechanics/animation-needs/ui-layout/checklist/decisions)· 本文件由 SSoT 編譯,不手動編輯視圖
原型:jsg-prototype-forge/prototypes/jsg01-dualfist-2p/ · 站 1~5 已完成,戴手環實機測試過