Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

分析工具

您可以從 Godot 運作遊戲並進行遊戲。它很有趣,它的功能正在變得完整,而且你感覺它已經接近發布了。

但是,當你打開技能樹時,它就會因為程式碼中的某些問題而停止運作。看著技能樹像幻燈片一樣滾動是不可接受的。什麼地方出錯?是定位技能樹元素、UI 還是渲染?

您可以嘗試優化所有內容並重複運作遊戲,但您可以對此更加聰明並縮小可能性。輸入戈多的分析器。

PCK 檔概覽

您可以透過開啟 偵錯器 面板並點擊 探查器 標籤來開啟探查器。

../../../_images/profiler.png

Godot 的分析器不會自動運作,因為分析是效能密集的。它必須不斷測量遊戲中發生的一切並向偵錯器報告,因此預設情況下它是關閉的。

要開始分析,請點擊左上角的 開始 按鈕。運作你的遊戲,資料將開始出現。您也可以在遊戲之前或遊戲過程中的任何時間開始分析,這取決於您是否願意。

備註

探查器目前不支援 C# 腳本。可以使用 JetBrains Rider 和 JetBrains dotTrace 以及 Godot 支援外掛程式來分析 C# 腳本。

您可以隨時點擊**清除**按鈕來清除資料。使用**測量**下拉式選單變更您測量的資料型別。測量面板和圖表將會相應更新。

精靈軌道

分析器的介面分為兩個。左側是功能列表,右側是效能圖。

主要測量是影格時間、物理影格、空閒時間和物理時間。

  • **影格時間**是 Godot 執行整個影像的所有邏輯(從物理到渲染)所需的時間。

  • 實體訊框 是 Godot 在實體更新之間指派的時間。在理想情況下,影格時間是您選擇的任何值:預設為 16.66 毫秒,對應於 60FPS。這是一個參考框架,您可以將其用於周圍的其他一切。

  • **空閒時間**是 Godot 更新實體以外的邏輯所花費的時間,例如位於「_process」中的程式碼或設定為在**空閒**上更新的計時器和相機。

  • 物理時間**是 Godot 更新物理工作所花費的時間,例如「_physical_process」和設定為 **Physics 更新的內建節點。

備註

在 Godot 3 中,**影格時間**包括渲染時間。假設您在遊戲中發現了神秘的延遲峰值,但您的物理和腳本都運作得很快。延遲可能是由於粒子或視覺效果的出現!

預設情況下,Godot 會勾選「影格時間」和「物理時間」。這可以讓您大致了解每個影格相對於分配的所需物理 FPS 所花費的時間。您可以透過點擊左側的複選框來開啟和關閉功能。當您沿著列表向下瀏覽時,會出現其他功能,例如“Physics 2D”、“Physics”和“Audio”,然後再到達顯示程式碼的腳本函式。

如果您按一下圖表,您可以變更左側顯示的框架資訊。右上角還有一個影格計數器,您可以在其中更精細地手動調整您正在查看的影格。

測量範圍和測量視窗

您可以使用**測量**下拉式選單變更您正在查看的測量結果。預設情況下,它以影格時間開始,並列出通過影格所需的時間(以毫秒為單位)。平均時間是任何給定函式被呼叫多次時所花費的平均時間。例如,一個需要 0.05 毫秒運作五次的函式應該會給您平均 0.01 毫秒。

如果精確的毫秒計數並不重要,並且您想要查看相對於影格其餘部分的時間比例,請使用百分比測量。影格 % 相對於影格時間,物理 % 相對於物理時間。

最後一個選項是時間範圍。 **包含**測量函式**與**任何巢狀函式呼叫所花費的時間。例如:

../../../_images/split_curve.png

get_neighborsfind_nearest_neighbormove_subject 都花了很多時間。您可能會誤以為這是因為它們三個都很慢。

但是當更改為 Self 時,Godot 會測量在函式體中花費的時間,而不考慮它自己進行的函式呼叫。

../../../_images/self_curve.png

您可以看到 get_neighborsmove_subject 已經失去了很多重要性。實際上,這意味著“get_neighbors”和“move_subject”花了更多時間等待其他函式呼叫完成,而“find_nearest_neighbor”實際上很慢。

對專案進行除錯

使用探查器尋找慢速程式碼可以歸結為運作遊戲並觀察繪製的效能圖。當影格時間內出現不可接受的尖峰時,您可以點擊圖表來暫停遊戲並將_Frame #_ 縮小到尖峰的開始處。您可能需要在框架和函式之間來回跳轉才能找到根本原因。

在腳本函式下,開啟某些函式的複選框以尋找哪些函式需要時間。這些是您需要檢查和優化的功能。

以微秒為單位手動測量

如果您的函式很複雜,那麼找出哪個部分需要最佳化可能會很困難。是你的數學還是你存取其他資料進行數學計算的方式?是「for」循環嗎? “if”敘述?

當程式碼使用一些臨時函式運作時,您可以透過手動計算刻度來縮小測量範圍。這兩個函式是「Time」類別物件的一部分。它們是“get_ticks_msec”和“get_ticks_usec”。第一個以毫秒為單位(每秒 1,000 個),第二個以微秒為單位(每秒 1,000,000 個)。

任一者都會返回自遊戲引擎在各自時間範圍內啟動以來的時間量。

如果您用微秒的開始和結束計數包裝一段程式碼,則兩者之間的差異就是運作該程式碼段所花費的時間。

# Measuring the time it takes for worker_function() to run
var start = Time.get_ticks_usec()
worker_function()
var end = Time.get_ticks_usec()
var worker_time = (end-start)/1000000.0

# Measuring the time spent running a calculation over each element of an array
start = Time.get_ticks_usec()
for calc in calculations:
    result = pow(2, calc.power) * calc.product
end = Time.get_ticks_usec()
var loop_time = (end-start)/1000000.0

print("Worker time: %s\nLoop time: %s" % [worker_time, loop_time])

當您成為一名更有經驗的程式設計師時,這種技術就變得不再那麼必要了。您開始了解正在運作的程式的哪些部分速度較慢。知道循環和分支可能會很慢來自於經驗,並且您可以透過測量和研究來獲得經驗。

但是在探查器和ticks函式之間,您應該有足夠的知識來開始搜尋程式碼的哪些部分需要最佳化。