尋路演算法:NPC 為什麼會卡牆

gaming%20setup%20with%20RGB%20keyboard%2C%20gaming...
發表時間:2026 年 10 月 29 日 | 更新日期:2026 年 10 月 29 日 | 編輯:雅寶社區編輯團隊
尋路演算法:NPC 為什麼會卡牆 - 雅寶社區 · 頂客論壇

  • 網格(Grid-based): 把世界切成整齊的方格,每格標記可走或不可走。實作簡單、除錯直觀,2D 遊戲與回合制戰棋幾乎都用這套。缺點是記憶體消耗與格子大小之間的取捨非常痛苦——格子太大,窄門過不去;格子太小,記憶體跟搜尋量都會爆炸。
  • 路徑點(Waypoint Graph): 由美術或關卡設計師手動擺放節點,再用連線表示可通行關係。路徑乾淨、效能極好,早期 FPS 與 MMO 大量使用。但節點是離散的,NPC 只會「照點走」,很容易走出折線感,且一旦節點擺放位置不良,NPC 就會一頭撞上節點與節點之間那面沒被考慮到的牆。
  • 導航網格(NavMesh): 用多邊形(通常是三角形或凸多邊形)鋪滿可行走區域,是現代 3D 遊戲的標準答案。Unity 的 NavMesh、Unreal 的 NavMesh、以及開源的 Recast/Detour 都屬於這類。NavMesh 的優勢是能精確描述不規則地形,但「烘焙(Bake)」參數只要有一項設定錯誤,整張導航圖就會出現肉眼看不到的破洞或錯誤連結。
  • 這裡要先建立一個重要觀念:導航資料結構描述的是「AI 認為可以走的地方」,而物理碰撞體描述的是「角色實際能不能穿過去的地方」。 這兩者如果沒有同步,NPC 就會出現「導航上這裡是路、物理上這裡是牆」的致命矛盾,也就是最經典的貼牆卡死。

    尋路 ≠ 移動:路徑規劃與轉向控制的雙層架構

    很多新手開發者會以為「找到路徑就等於會走」,但實際上 NPC 的移動至少牽涉三層:

  • 路徑規劃層(Path Planning): 用 A* 之類的演算法在導航圖上算出一串路徑點。
  • 路徑跟隨層(Path Following): 把路徑點做平滑處理(例如 Catmull-Rom、Bezier),產生更自然的曲線,並控制 NPC 沿著曲線前進。
  • 轉向與避障層(Steering & Avoidance): 處理實際的速度、加速度、轉向半徑,以及與其他角色或動態物件的即時避讓(例如 RVO、ORCA)。
  • 卡牆最常發生的地方,往往不是第一層,而是第二層與第三層。因為路徑規劃是在抽象圖上進行的,它不知道「平滑後的曲線會切過牆角」,也不知道「角色轉向半徑太大,過不了那個九十度彎」。這也是為什麼很多 NPC 的行為看起來像「明明知道路,卻走得亂七八糟」——它的腦袋知道路,但身體不聽話。

    二、NPC 卡牆的十大元凶

    接下來這十個原因,涵蓋了從資料層、演算法層到行為層的常見翻車現場。你可以把它當成一份除錯清單,遇到 NPC 卡住時,從上往下逐一排查,命中率通常不低。

    元凶一:路徑節點與碰撞體不一致

    這是最經典、也最常見的原因。導航網格烘焙時,場景中的牆體、欄杆、箱子如果沒有被正確標記為「靜態幾何(Static Geometry)」,就會被烘焙流程忽略,導致導航網格直接穿過牆體。於是 NPC 的尋路結果告訴它「往前直走可以到」,但物理引擎說「不行,這裡有牆」。NPC 就會不斷嘗試往前走,撞牆、被推回、再往前走,形成貼牆抖動的畫面。

    反過來也有另一種情況:導航網格烘焙得太保守,把一些實際上可以通過的窄縫判定為不可走,NPC 就會莫名其妙地繞一大圈,或者在狹窄處來回猶豫。這類問題通常要在開發階段用視覺化工具把 NavMesh 疊在場景上檢查,才看得出破洞在哪。

    元凶二:啟發函數(Heuristic)設計錯誤

    前面提過,A* 的效能與正確性都依賴啟發函數。如果 h(n) 估得太高,A* 會變得貪婪,可能找到一條「看起來很近、實際很繞」的路徑;如果 h(n) 跟移動模型不匹配(例如在六角格地圖用曼哈頓距離),路徑品質就會下降。更麻煩的是,某些專案為了效能會刻意使用「權重式 A*(Weighted A*)」,把 h 乘以一個大於 1 的係數來加速搜尋,代價就是路徑可能不是最短,NPC 就容易走出貼牆的彆扭路線。

    元凶三:動態障礙物沒有重算路徑

    靜態場景烘焙好之後,一旦遊戲中出現會移動的障礙物——關起來的門、被推倒的書架、臨時生成的岩漿池——原本的路徑就作廢了。如果 AI 沒有機制去偵測「路徑上出現新障礙」,NPC 就會照著舊路徑一頭撞上去。有些引擎提供 NavMesh Obstacle 元件,可以在障礙物出現時挖掉(Carve)對應區域並要求附近角色重算路徑,但這個功能有成本,很多專案會設定「只對玩家附近生效」或「每隔幾秒才更新一次」,於是就出現 NPC 卡在動態門口的經典畫面。

    元凶四:路徑平滑化(Path Smoothing)切過牆角

    這是很多開發者會忽略的隱形殺手。A* 產生的原始路徑是沿著網格中心的折線,看起來很機械,所以大家會做平滑化,把它變成漂亮的曲線。但問題是:平滑後的曲線可能切進牆角。特別是當路徑在轉角處有兩個相鄰節點,平滑演算法為了圓滑,會把曲線往內側拉,結果就是 NPC 的實際移動軌跡穿過了牆體邊緣,被物理引擎擋住,然後它就卡在那裡了。

    正確的做法是在平滑化之後,對每一段曲線做碰撞檢測(例如 Capsule Cast),確認整條平滑路徑都在可行走區域內;或者改用「弦切角」受限的平滑演算法,限制曲線與原始路徑的最大偏移量。

    元凶五:尋路網格解析度不足

    格子太大,窄門就會被判定為不可通行;格子太小,記憶體與搜尋成本又會暴增。這個取捨在手機遊戲或大型開放世界中特別明顯。有些專案會用「多層解析度」來折衷:大格子做粗尋路,小格子只在角色附近做細部修正。但如果兩層之間的連結沒有處理好,NPC 就會在粗細網格的交界處迷路,出現「明明看得到門卻走不進去」的狀況。

    另一個相關參數是 Agent Radius(角色半徑)。如果你的 NPC 是體型較大的 Boss,但導航網格是用小兵半徑烘焙的,那麼 Boss 就會不斷嘗試穿越它實際上過不去的通道,然後卡死。這是很多動作遊戲 Boss 戰卡牆的主因之一。

    元凶六:轉向半徑與避障邏輯衝突

    尋路演算法通常假設角色可以「原地轉向」或「瞬間改變方向」,但實際的轉向控制(Steering)會給角色一個最大轉向角速度與最小轉向半徑。當路徑要求 NPC 做一個急轉彎,而它的轉向半徑又不夠小時,它就會衝過頭、撞牆,然後試圖回頭,形成來回擺盪的抽搐行為。

    同樣的問題也會發生在群體避障(RVO、ORCA)上。當多個 NPC 同時擠向一個窄門,避障演算法會互相把對方推開,導致某些 NPC 被推離原路徑、撞上牆壁,而它們的狀態機又沒有「重新尋路」的機制,於是就永遠卡在牆邊。

    元凶七:多執行緒與非同步尋路的時序問題

    現代遊戲為了效能,尋路通常會丟到背景執行緒(Worker Thread)去算,算完再把結果送回主執行緒套用。這就產生了「路徑過期(Stale Path)」的問題:當背景執行緒花了 50 毫秒算出路徑時,目標可能已經移動了,或者玩家已經把門關上了。如果系統沒有用版本號、時間戳或「目標位移閾值」來判斷路徑是否還有效,NPC 就會拿著一張過期的地圖導航,然後撞牆。

    更糟的是,如果多個尋路請求同時進行,而結果回傳的順序錯亂,NPC 可能會拿到「上一個目標」的路徑,然後往錯誤的方向跑。這類 Bug 在測試環境很難重現,但在玩家電腦上卻層出不窮。

    元凶八:狹窄通道與群體推擠

    當十幾個 NPC 同時要通過一扇窄門,而每個角色都有碰撞體積時,就會出現「瓶頸死鎖」:大家互相卡住,誰也過不去。這種情況在攻城戰、村莊巡邏、或是寵物跟隨系統中特別常見。解決方式包括設定優先級(讓隊長先走)、排隊機制、或是讓部分角色暫時關閉碰撞(但這會產生穿模的副作用),需要針對遊戲體驗做取捨。

    元凶九:NavMesh 烘焙(Bake)參數不當

    NavMesh 烘焙有一堆參數,每一個都可能讓 NPC 卡牆:

    Cell Size: 決定網格精度,太粗會漏掉細節。

  • Agent Radius / Height: 決定角色能通過的通道寬度與頭頂淨空。
  • Max Slope: 超過此角度的斜坡被視為不可走,設定太嚴格會讓 NPC 上不了緩坡。
  • Step Height: 能跨越的台階高度,設定太低會讓 NPC 被樓梯卡住。
  • Min Region Area: 太小的導航區域會被自動刪除,可能導致某些小平台或陽台無法抵達。
  • 這些參數必須根據遊戲中所有角色的體型與移動能力來設定。如果你的遊戲同時有小老鼠 NPC 和巨龍 Boss,通常需要烘焙多張不同 Agent 設定的 NavMesh,並在執行時動態切換。

    元凶十:狀態機與尋路中斷

    最後一個常見原因是行為邏輯本身的 Bug。NPC 的行為通常由狀態機(State Machine)或行為樹(Behavior Tree)控制,例如「巡邏 → 發現敵人 → 追擊 → 攻擊」。如果狀態切換時沒有正確清理舊路徑,或者攻擊動畫鎖住了移動輸入,NPC 就可能出現「站在牆邊一直播放攻擊動畫」或「路徑已清空卻仍在原地轉圈」的狀況。這類問題通常要搭配行為日誌(Behavior Log)與視覺化狀態機來除錯。

    三、實戰案例:那些年我們一起卡住的 NPC

    理論講完了,來看看幾個玩家最有感的實際案例。這些情境幾乎涵蓋了前面十種元凶的組合,也是各大遊戲論壇上最常被回報的 Bug 類型。

    案例一:城門口永遠走不進去的衛兵

    某款 MMO 的玩家發現,主城門口的衛兵會在巡邏到城門時卡住,貼著門框左右抖動,永遠走不進城內。追查後發現,城門是動態物件(會定時開關),而製作團隊只在城門「開啟」狀態下烘焙了 NavMesh,卻沒有處理「關閉」狀態的導航更新。當城門關上時,衛兵的路徑仍然穿過門的位置,於是它就一頭撞上門板,尋路系統每幀都告訴它「往前走」,物理系統每幀都把它推回來,形成永恆的抖動。

    這類 Bug 的修法通常有兩種:一是把城門設為 NavMesh Obstacle,關閉時自動挖掉該區域並觸發周邊角色重算路徑;二是改用觸發器(Trigger)在門關閉時直接讓衛兵切換巡邏路線。前者彈性高但成本較大,後者簡單但需要針對每個場景手動設定。

    案例二:Boss 戰中穿牆失敗的追擊型敵人

    動作遊戲中常見的大型 Boss,在追擊玩家時會試圖直接穿過柱子或矮牆,結果卡在障礙物旁邊。原因通常有兩個:第一,Boss 的 Agent Radius 遠大於小兵,但專案只烘焙了一張以一般角色為準的 NavMesh,導致 Boss 的尋路結果穿越了它實際上過不去的狹窄通道;第二,Boss 的轉向半徑太大,即使路徑正確,它也無法在狹窄空間內完成轉彎。

    進階的解法是為 Boss 單獨烘焙一張 Agent 較大的 NavMesh,或者在狹窄處設置「Boss 不可進入」的導航遮罩(NavMesh Modifier),讓尋路系統直接避開這些區域。有些遊戲甚至會讓 Boss 在卡住超過一定時間後,直接播放「破牆」或「瞬移」的演出,把 Bug 轉化成遊戲特色。

    案例三:跟隨型寵物在樓梯間的抽搐

    寵物跟隨是幾乎每款 RPG 都會做的功能,也是最容易卡牆的地方。常見情境是:玩家走上樓梯,寵物在後面跟隨,卻在樓梯轉角處卡住,一下往上、一下往下,像在跳機械舞。這通常是因為樓梯的 Step Height 設定不當,階梯被判定為「可跨越」與「不可跨越」的邊界地帶,導致尋路結果在相鄰兩階之間反覆跳動。

    另一個原因是跟隨邏輯的目標點更新太頻繁。如果寵物每一幀都重新計算到玩家位置的路径,而玩家又在移動,路徑就會不斷被覆寫,寵物永遠走不完第一段路徑。比較好的做法是設定「路徑重算閾值」——只有當玩家移動超過一定距離,或寵物偏離路徑超過一定角度時,才重新尋路。

    四、玩家視角:遇到 NPC 卡牆怎麼辦

    身為玩家,我們無法修改遊戲程式碼,但還是可以透過一些操作來「繞過」AI 的Bug。以下幾個方法在多數遊戲中都有一定效果:

    常見遊戲內的破解手法

  • 離開 NPC 的視野範圍再回來: 很多遊戲的 AI 會在玩家離開一定距離後重置狀態,卡住的 NPC 可能因此重新尋路。
  • 切換場景或使用傳送: 讀取畫面通常會重置場景內所有 AI 的路徑,是最有效的「萬用解」。
  • 攻擊 NPC 或引導它移動: 部分遊戲的受擊反應會強制打斷當前尋路狀態,讓 NPC 重新計算。
  • 改變自己的站位: 如果 NPC 是為了追你而卡住,換個位置可能讓它的新路徑繞過障礙物。
  • 使用「脫困」或「跟隨」指令: 有些 MMORPG 提供寵物召回、NPC 傳送等便利功能,直接繞過尋路問題。
  • 回報 Bug 的正確姿勢

    如果你希望這個問題被修好,回報時請盡量提供:遊戲版本、角色座標、當時的任務狀態、NPC 名稱、以及一段能重現的錄影。最好能附上「重現步驟」,例如「從村莊東門沿著圍牆走,護送 NPC 到鐵匠鋪時必定卡在第二個轉角」。對開發團隊來說,有座標與影片的 Bug 回報,修復效率會比「NPC 卡住了」高出十倍以上。

    五、開發者視角:如何避免 NPC 卡牆

    如果你正在開發遊戲,以下幾件事可以大幅降低 NPC 卡牆的機率。它們不見得能解決所有問題,但至少能讓你在 Bug 發生時快速定位。

    除錯工具與視覺化

    第一件事:把 NavMesh、路徑、Agent 狀態全部畫出來。Unity 的 NavMesh 視覺化、Unreal 的 Navigation Mesh 顯示、以及自行用 Gizmos 繪製路徑點與轉向向量,都是基本配備。當你能看到「AI 認為可以走的地方」與「實際碰撞體」之間的差異,八成以上的卡牆原因會立刻現形。

    第二件事:建立導航圖的連通性檢查。在關卡載入時,自動檢查所有應該互相連通的區域是否真的連通,並在編輯器或測試報告中標記出來。很多卡牆問題其實是關卡設計改動後,NavMesh 沒有重新烘焙造成的,自動化檢查可以提早攔截這類錯誤。

    設計層面的防呆

    再好的 AI 也會有出錯的時候,所以遊戲設計上要有「保險機制」:

  • 卡住偵測: 如果 NPC 的位置在數秒內幾乎沒有變化,但狀態仍是「移動中」,就觸發重新尋路或短距離傳送。
  • 路徑失效檢查: 定期驗證目前路徑是否仍然有效(例如路徑上的節點是否還可通行),失效就重算。
  • 通道寬度留餘裕: 關卡設計時,讓主要通道寬度至少是最大 Agent 直徑的兩倍以上,避免極限穿越。
  • 避免直角窄門: 直角轉角是平滑路徑與轉向半徑最容易出事的地方,改用斜角或加大轉角空間可以有效改善。
  • 為大型角色單獨烘焙導航網格: 不要讓 Boss 跟小兵共用同一張導航圖。
  • 最後,把「NPC 卡住」當成一種必然會發生的狀況來設計,而不是假設它不會發生。很多 3A 遊戲都會在 NPC 卡住超過一定時間後,直接讓它傳送到最近的導航點,或者播放一個「我迷路了」的語音來掩蓋,這不是偷懶,而是務實的工程取捨。

    結語:卡牆不是 Bug,是演算法與世界的對話

    NPC 卡牆看起來像是一個簡單的程式錯誤,但背後其實是尋路演算法、導航資料、物理碰撞、轉向控制與行為邏輯五個系統之間的複雜互動。任何一個環節的參數歪掉,或是任何兩個系統之間的假設不一致,都會讓 NPC 在玩家面前演出各種荒謬的卡牆喜劇。

    對玩家來說,理解這些原理之後,下次看到 NPC 貼牆抽搐,也許就能會心一笑,甚至猜到是哪個參數沒調好;對開發者來說,把導航網格、路徑平滑與轉向控制當成一個整體來設計,並加上足夠的視覺化與防呆機制,才是讓 NPC 真正「走得像人」的關鍵。畢竟,一個不會卡牆的 NPC,才是玩家願意相信它真的存在于那個世界裡的第一步。

    如果你在遊戲裡遇到什麼奇葩的 NPC 卡牆現場,歡迎在雅寶社區 · 頂客論壇的遊戲攻略版分享,附上影片與座標,說不定下一個被我們拆解的案例,就是你的親身經歷。

    ```

    🏠 返回首頁