Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
常見引擎方法與巨集¶
Godot 的 C++ 原始碼中使用了數十種自定方法與巨集,且幾乎所有檔案中都有用到。本頁主要是提供給剛開始參與貢獻的人看,但對於撰寫自定 C++ 模組的人來說應該也很實用。
印出文字¶
// Prints a message to standard output.
print_line("Message");
// Non-String arguments are automatically converted to String for printing.
// If passing several arguments, they will be concatenated together with a
// space between each argument.
print_line("There are", 123, "nodes");
// Prints a message to standard output, but only when the engine
// is started with the `--verbose` command line argument.
print_verbose("Message");
// Prints a rich-formatted message using BBCode to standard output.
// This supports a subset of BBCode tags supported by RichTextLabel
// and will also appear formatted in the editor Output panel.
// On Windows, this requires Windows 10 or later to work in the terminal.
print_line_rich("[b]Bold[/b], [color=red]Red text[/color]")
// Prints a formatted error or warning message with a trace.
ERR_PRINT("Message");
WARN_PRINT("Message");
// Prints an error or warning message only once per session.
// This can be used to avoid spamming the console output.
ERR_PRINT_ONCE("Message");
WARN_PRINT_ONCE("Message");
若需要在訊息中新增預留位置,可以使用如下說明的格式化字串。
格式化字串¶
vformat()
函式會回傳經過格式化的 String 。其行為與 C 的 sprintf()
類似:
vformat("My name is %s.", "Godette");
vformat("%d bugs on the wall!", 1234);
vformat("Pi is approximately %f.", 3.1416);
// Converts the resulting String into a `const char *`.
// You may need to do this if passing the result as an argument
// to a method that expects a `const char *` instead of a String.
vformat("My name is %s.", "Godette").c_str();
大多數情況下,使用 vformat()
來代替字串串接可以提升程式碼的可讀性。
將整數或浮點數轉為字串¶
使用 print_line() 列印數字時不需要這樣做,但您可能仍需要對其他一些用例執行手動轉換。
// Stores the string "42" using integer-to-string conversion.
String int_to_string = itos(42);
// Stores the string "123.45" using real-to-string conversion.
String real_to_string = rtos(123.45);
在地化字串¶
在 Godot 的程式碼中有兩種方法來進行在地化:
TTR()
: 編輯器 ("Tools") 翻譯 - Tools TRanslation 只能在編輯器中實用。若使用者在專案中使用了相同的文字,若沒有提供用於該文字的翻譯,就不會被翻譯。在參與引擎貢獻時,用來翻譯字串的巨集通常都是這個。RTR()
: 執行階段翻譯 - Run-time TRanslations 檔有提供給定字串的翻譯時,會在專案內自動翻譯。這種翻譯通常不會用在編輯器程式碼內。
// Returns the translated string that matches the user's locale settings.
// Translations are located in `editor/translations`.
// The localization template is generated automatically; don't modify it.
TTR("Exit the editor?");
若要在可翻譯字串內插入預留位置,請如下範例以 vformat()
呼叫包住在地化巨集:
String file_path = "example.txt";
vformat(TTR("Couldn't open \"%s\" for reading."), file_path);
備註
當將 vformat()
與翻譯巨集一起使用時,請務必將翻譯巨集包在 vformat()
內,而不要反過來。否則產生的字串永遠不會有對應的翻譯,因為在傳給 TranslationServer 時,字串的預留位置已經被換掉了。
鉗制數值¶
Godot 提供了用來將數值鉗制在最小值 (MAX
) 與最大值 (MIN
) 以及同時鉗制 (CLAMP
) 的巨集:
int a = 3;
int b = 5;
MAX(b, 6); // 6
MIN(2, a); // 2
CLAMP(a, 10, 30); // 10
這幾個巨集可以用在所有能互相比較的型別內 (如 int
與 float
)。
微型效能評定 (Microbenchmarking)¶
若想對一小部分的程式碼進行效能評定,但不知道要如何實用分析工具,則可以使用下列程式碼片段:
uint64_t begin = OS::get_singleton()->get_ticks_usec();
// Your code here...
uint64_t end = OS::get_singleton()->get_ticks_usec();
print_line(vformat("Snippet took %d microseconds", end - begin));
這個程式會印出介於 begin
宣告與 end
宣告間所花費的時間。
備註
若程式碼中沒有 #include "core/os/os.h"
,則需要包含這行程式。
如果一開始沒有這段程式碼的話,請確定在開啟 Pull Request 時有移除這段程式。
取得專案或編輯器設定¶
有四種可用於取得設定的巨集:
// Returns the specified project setting's value,
// defaulting to `false` if it doesn't exist.
GLOBAL_DEF("section/subsection/value", false);
// Returns the specified editor setting's value,
// defaulting to "Untitled" if it doesn't exist.
EDITOR_DEF("section/subsection/value", "Untitled");
如果有在其他地方指定預設值的話,則請不要指定預設值以避免重複:
// Returns the value of the project setting.
GLOBAL_GET("section/subsection/value");
// Returns the value of the editor setting.
EDITOR_GET("section/subsection/value");
建議每個設定只使用一次 GLOBAL_DEF
/EDITOR_DEF
,然後在其他參照的地方使用 GLOBAL_GET
/EDITOR_GET
。
錯誤巨集¶
Godot 提供了許多能讓錯誤回報更方便的錯誤巨集。
警告
在錯誤巨集中的條件式與 GDScript 的內建 assert()
函式運作的方法 相反 。錯誤會在其中的條件式為 true
時跑出,而非 false
。
備註
這裡只寫了幾種自定訊息的變體,因為我們建議所有新的貢獻者都應該只使用這些型別的訊息。請確保自定訊息有包含足夠的訊息來讓使用者即使不瞭解 C++ 也能診斷問題。當將無效的參數傳給某個方法時,可以將無效的值印出以讓除錯過程更簡單。
對於不需要顯示人類可讀取訊息的內部錯誤檢查,可以移除巨集後方的 _MSG
,然後不提供訊息參數。
另外,也請務必回傳可處理的資料,以讓引擎繼續執行。
// Conditionally prints an error message and returns from the function.
// Use this in methods which don't return a value.
ERR_FAIL_COND_MSG(!mesh.is_valid(), vformat("Couldn't load mesh at: %s", path));
// Conditionally prints an error message and returns `0` from the function.
// Use this in methods which must return a value.
ERR_FAIL_COND_V_MSG(rect.x < 0 || rect.y < 0, 0,
"Couldn't calculate the rectangle's area.");
// Prints an error message if `index` is < 0 or >= `SomeEnum::QUALITY_MAX`,
// then returns from the function.
ERR_FAIL_INDEX_MSG(index, SomeEnum::QUALITY_MAX,
vformat("Invalid quality: %d. See SomeEnum for allowed values.", index));
// Prints an error message if `index` is < 0 >= `some_array.size()`,
// then returns `-1` from the function.
ERR_FAIL_INDEX_V_MSG(index, some_array.size(), -1,
vformat("Item %d is out of bounds.", index));
// Unconditionally prints an error message and returns from the function.
// Only use this if you need to perform complex error checking.
if (!complex_error_checking_routine()) {
ERR_FAIL_MSG("Couldn't reload the filesystem cache.");
}
// Unconditionally prints an error message and returns `false` from the function.
// Only use this if you need to perform complex error checking.
if (!complex_error_checking_routine()) {
ERR_FAIL_V_MSG(false, "Couldn't parse the input arguments.");
}
// Crashes the engine. This should generally never be used
// except for testing crash handling code. Godot's philosophy
// is to never crash, both in the editor and in exported projects.
CRASH_NOW_MSG("Can't predict the future! Aborting.");
也參考
有關各個錯誤巨集的更多資訊,請參考 Godot 原始碼中的 core/error_macros.h 。
有些函式會回傳錯誤程式碼 (具體化為使用 Error
回傳型別)。該錯誤程式碼的值可以直接在錯誤巨集中回傳。有關可用的錯誤程式碼列表,請參考 core/error_list.h 。