Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

物理問題疑難排解

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

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

高速移動時物件互相穿透

This is known as tunneling. Enabling Continuous CD (Continuous Collision Detection) in the RigidBody properties can sometimes resolve this issue. If this does not help, there are other solutions you can try:

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

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

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

堆疊的物件不穩定且晃動

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

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

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

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

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

Since resources are shared by default, you'll have to make the collision shape resource unique if you don't want the change to be applied to all nodes using the same collision shape resource in the scene. This can be done in two ways:

  • In the editor, by clicking Make Unique in the CollisionShape resource dropdown in the inspector, then changing its size.

  • In a script, by calling duplicate() in a script on the collision shape resource before changing its size.

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

這通常有兩個可能原因:

  • 地板的碰撞形狀太薄。

  • 剛體(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) 來緩解。

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

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