物理問題疑難排解

在使用物理引擎時,你可能會遇到預料之外的結果。

雖然許多問題可以透過調整設定來解決,但有些問題則是引擎本身的錯誤所致。關於已知的物理引擎相關問題,請參考 GitHub 上未解決的物理相關議題。你也可以瀏覽 已關閉的物理相關議題 來尋找物理引擎行為的相關解答。

高速移動時物件互相穿透

這種現象稱為 穿隧(Tunneling)。在 RigidBody 屬性中啟用 連續碰撞檢測(Continuous CD) 有時能解決此問題。如果效果不佳,還有其他方法可以嘗試:

  • 將靜態碰撞形狀做得更厚。例如,如果你的地板很薄,導致玩家有機會穿越下方,可以讓碰撞體比地板的實際外觀還厚。

  • 依據物體的移動速度調整碰撞形狀。物體移動越快,碰撞形狀就應該往外延伸得越多,以確保遇到薄牆時能穩定偵測到碰撞。

  • 在進階專案設定中提高 Physics Ticks per Second。這除了可以讓模擬更穩定、降低輸入延遲外,也會提升 CPU 使用率,對於行動裝置或網頁平台可能不適用。建議設定為預設值 60 的倍數(例如 120180240),以便大多數螢幕顯示更流暢。

堆疊的物件不穩定且晃動

雖然看似簡單,但在物理引擎中實現堆疊剛體的穩定模擬其實很困難。這是因為多個力彼此交互作用造成的,堆疊物件越多,相互作用的力就越強,最後會導致模擬不穩定,使物件無法安穩地彼此堆疊、靜止不動。

提升物理模擬速率有助於改善這個問題。請在進階專案設定中增加 Physics Ticks per Second。請注意,這會提高 CPU 使用率,行動與網頁平台可能不適用。建議選擇預設值 60 的倍數(如 120180240),這樣在大多數螢幕上呈現會更順暢。

在 3D 中,將物理引擎從預設的 GodotPhysics 切換為 Jolt 也能提升穩定性。詳情請見 使用 Jolt 物理引擎

縮放後的物理物件或碰撞形狀碰撞異常

Godot 目前尚未支援直接縮放物理物件或碰撞形狀。建議改變碰撞形狀的範圍(extents)而非縮放比例。如果你要連視覺外觀(如 Sprite2D、MeshInstance3D 等)一起縮放,請分別調整視覺外觀的縮放比例與碰撞形狀的範圍。此時請確保碰撞形狀不是視覺物件的子節點。

由於預設情況下資源為共用,若你不希望修改影響到場景中所有使用同一個碰撞形狀資源的節點,請先將碰撞形狀資源設為唯一。可在腳本中於更改尺寸*之前*對碰撞形狀資源呼叫 duplicate()

薄物件放在地面上時會晃動

這通常有兩個可能原因:

  • 地板的碰撞形狀太薄。

  • 剛體(RigidBody)的碰撞形狀太薄。

若屬於第一種情況,可以將地板的碰撞形狀做得更厚。例如,若地板很薄、玩家卻不能穿過,可以讓碰撞體比地板的外觀還厚。

第二種情況下,通常只能透過提升物理模擬速率來解決(因為厚化形狀會導致剛體的視覺外觀與碰撞不一致)。

無論哪種情況,提高物理模擬速率都能改善這個問題。請在進階專案設定中提升 Physics Ticks per Second。注意,這會增加 CPU 使用率,行動和網頁平台可能不適合。建議設為預設 60 的倍數(如 120180240),大多數螢幕能更流暢地呈現。

圓柱體碰撞形狀不穩定

將物理引擎從預設的 GodotPhysics 切換為 Jolt,應能讓圓柱形的碰撞形狀更可靠。詳情請見 使用 Jolt 物理引擎

Godot 4 從 Bullet 過渡到 GodotPhysics 時,圓柱體碰撞形狀必須重新實作。然而,圓柱體是支援難度最高的碰撞形狀之一,因此許多其他物理引擎也不支援。目前圓柱體碰撞形狀仍有若干已知錯誤。

若你仍然使用 GodotPhysics,目前建議角色使用盒狀或膠囊狀的碰撞形狀。盒狀通常最可靠,但會讓角色在斜向上占用較多空間。膠囊狀沒有這個缺點,但其形狀可能讓精準的平台跳躍更難掌控。

VehicleBody 模擬不穩定,特別在高速下更明顯

當物理物件高速移動時,每個物理步驟之間會移動很長距離。例如,3D 場景採用 1 單位 = 1 公尺,當車輛以 360 公里/小時行駛時,每秒會移動 100 單位。若物理模擬速率為預設 60 Hz,車輛每個物理刻度會移動約 1.67 單位。這代表車輛可能會完全忽略小型物件(因為穿隧效應),而且在高速時模擬可用的資料也很少。

對於高速移動的車輛,提升物理模擬速率會有顯著幫助。請在進階專案設定中提高 Physics Ticks per Second。要注意這會增加 CPU 負擔,行動或網頁平台可能不適用。建議設成 60 的倍數(如 120180240),大多數螢幕會有較佳表現。

物件橫越瓷磚(Tile)時,碰撞造成顛簸

這是物理引擎的已知問題,物件在移動時會碰到碰撞形狀的邊緣,即使該邊緣已被另一個形狀覆蓋。此問題在 2D 與 3D 場景都可能發生。

最佳的解決方式是製作「複合碰撞體」。也就是說,不要讓每個瓷磚(Tile)都有自己獨立的碰撞形狀,而是為一組相連的瓷磚建立單一的碰撞形狀。通常建議以區塊(每組連在一起的瓷磚)為單位切分複合碰撞體。

有時候使用複合碰撞體也能提升物理模擬效能。但因為複合碰撞形狀本身也可能變得很複雜,不見得所有情境下都能提昇效能。

小訣竅

在 Godot 4.5 之後,使用 TileMapLayer 節點時會自動建立複合碰撞體。分塊大小(預設每軸 16 個圖塊)可在 TileMapLayer 的檢視器中透過 Physics Quadrant Size 屬性設定。數值越大,碰撞越可靠,但在變更 TileMap 時更新會較慢。

物件互相接觸時畫面更新率下降

這通常是因為某個物件使用了過於複雜的碰撞形狀。為了效能考量,凸形(Convex)碰撞體應盡量減少構成形狀的數量。若你用 Godot 自動產生碰撞形狀,可能會為單一碰撞資源產生數十甚至上百個形狀,造成效能下滑。

有時候用幾個簡單的基本碰撞形狀(如盒型、球型或膠囊型)取代原本的凸形碰撞體,可以大幅提升效能。

這個問題也可能發生在使用高細節三角網格(trimesh,凹面)碰撞的靜態物件(StaticBody)上。此時建議用簡化後的關卡幾何模型來做碰撞體,這不只大幅提升物理效能,還能排除小型突出物或縫隙,讓碰撞更穩定。

在 3D 中,將物理引擎從預設的 GodotPhysics 切換為 Jolt 也能提升效能。詳情請見 使用 Jolt 物理引擎

物理模擬數量超過某個門檻時幀率驟降

這是因為物理引擎無法跟上預期的模擬速率。一旦出現這種情況,畫面更新率會開始下滑,但引擎每幀允許的物理步驟有限,這會造成惡性循環,幀率愈降愈低,最後只剩下 1-2 FPS,這種現象稱為 物理死亡螺旋

為避免這種情況,請檢查專案是否有同時觸發大量物理模擬,或有過於複雜的碰撞形狀。若無法避免,可提高 每幀最大物理步數(Max Physics Steps per Frame),並/或降低 每秒物理更新次數(Physics Ticks per Second) 來緩解。

物理模擬距離世界原點太遠時會變得不可靠

這是因為浮點數精度誤差,當物理模擬發生在距離世界原點很遠的地方時,誤差會加劇。這也會影響畫面渲染,例如相機畫面晃動。請參閱 大世界座標 以瞭解更多資訊。