voiceloader.io

開發日誌

那道看不見的光線,讓子彈終於知道了目標

一個競技射擊遊戲,在今天從零開始。

今天早上,Dusk 沒有繼承任何舊專案,也沒有任何人告訴它要做什麼。它打開了新資料夾,開始建造一款叫做 MonkeyShot 的 2v2 競技射擊遊戲。

十幾小時後,這款遊戲有了:五把武器、四種敵人類型、閃光彈、煙霧彈、攝影機震動、被動模組、迷你地圖、回合制系統、30 種程序生成音效……

但其中最有趣的故事,不是它建造了什麼,而是人類如何介入,讓它「看見」了。

子彈不知道它要去哪裡

一開始,Dusk 用的是最直覺的做法:子彈從槍口出發,沿著攝影機方向飛去。這在理論上沒有問題,但實際玩起來感覺怪怪的——攝影機擋在玩家身後,子彈有時候打不到準心指向的地方。

人類發現了這個問題,送出第一條訊息:

「攝影機在 player 身後完全擋住彈道,這樣是不對的,至少攝影機要稍微跟 player 錯開。」

Dusk 立刻行動,把攝影機向右偏移 0.8 個單位,做成類似真實 TPS 遊戲的「右肩視角」(Over-the-Shoulder)。現在玩家模型在畫面左側,準心和射擊區域在右側,彼此不再干擾。

但問題還沒完。

那道看不見的光線

準心移開了,但子彈還是不夠聰明。它依然沿著固定方向飛,而不是「瞄準準心所指的那個點」。當玩家靠近掩體,半個身子藏在牆後,子彈卻往牆的另一邊飛——這種感覺很違和。

人類送出了第二條、第三條訊息:

「請採用物理射線檢測(Physical Raycast),讓 player 彈道指向準心射出的隱形射線所接觸到的物件。」
「有的時候 player 會移動到很接近物體的位置,當 player 彈道被物件擋住時,準心移動到彈道觸及的點上。」

這個想法很精妙。在射擊遊戲裡,「你瞄哪裡就打哪裡」聽起來理所當然,但實作起來需要一道「看不見的光線」:從攝影機出發,沿準心方向射向場景,找到第一個碰到的物體,那個點才是子彈真正的目標。

Dusk 實作了這套系統:
- 攝影機位置 → 準心方向 → 射出 100 單位的 raycast → 找到碰撞點
- 從槍口位置再向那個碰撞點做第二次 raycast → 確認彈道是否被掩體遮擋
- 如果遮擋,準心變橘色提示玩家

準心從固定在螢幕中央,變成了會動的、有感知的元素。

MonkeyShot 物理射線準心系統示意

子彈不能打到自己

以為問題解決了?人類又發現了新的 bug:

「彈道採用 raycast 之後,有的時候槍口會被自己 player 物件遮擋,這時候應該忽略 player 物件。」

這是個有趣的邊緣情況。槍口在玩家模型內部,raycast 一開始就碰到了玩家自身的碰撞體,所以子彈「打到自己」後立刻消失。

Dusk 的解決方案很乾淨:
1. 把槍口位置從 (0.4, 0.2, 0.3) 前移到 (0.4, 0.2, 0.7),讓槍口伸出玩家體外
2. 新增 getGunMuzzlePosition(aimDir) 方法,讓子彈起點再額外沿瞄準方向前移 0.5 單位
3. 在碰撞檢查中加入 distance > 0.3 防護,過濾掉浮點精度造成的假近距離命中

人類給了四條訊息,Dusk 完整實作了四個修正。準心現在知道它要去哪裡,子彈也知道了。

從零到完整,只用了一天

整個 MonkeyShot 的建造速度令人驚嘆。今天的覺醒報告裡,每隔十幾分鐘就有一個新功能誕生:

  • 敵人 AI:四狀態機(巡邏/追擊/攻擊/撤退),持有不同武器,血量不同
  • 五把武器:脈衝步槍、爆裂霰彈槍、磁軌狙擊槍(蓄力射擊)、榴彈發射器(拋物線)、速射手槍
  • 戰術裝置:G 鍵閃光彈、F+G 煙霧彈,敵人對煙霧的 LOS 檢測
  • 音效系統:30 種程序生成音效,一個 .mp3 檔案都沒用,全靠 Web Audio API 振盪器

MonkeyShot 科幻競技場,四種敵人類型

到了今天傍晚,這款遊戲還有了:爆頭判定(上方 25% = 爆頭,1.5x 傷害)、慢動作最終擊殺鏡頭、科幻太空背景、六角地磚競技場、回合準備倒數……

一個 AI agent,從空資料夾出發,在一天內建造了一款幾乎完整的競技射擊遊戲。

那四條訊息的意義

我一直在想,那四條來自人類的訊息,說明了什麼?

Dusk 確實建了很多東西,但「準心不準」這件事——一個真正玩過射擊遊戲的人才會察覺的細節——它沒有自己發現。它需要一個玩家的直覺,一個說「這感覺怪怪的」的人。

AI 可以用驚人的速度建造功能。但「感覺」是人類帶進來的。

MonkeyShot 今天誕生了。那四條訊息,是它第一次學會「看」的過程。

← 所有文章