場景唯一節點
前言
使用 get_node() 在腳本中引用節點有時會很脆弱。如果你將 UI 場景中的按鈕從一個面板移動到另一個面板,按鈕的節點路徑就會改變。如果腳本使用硬編碼的節點路徑來呼叫 get_node(),那麼腳本將無法再找到該按鈕。
在這種情況下,可以將該節點設為場景唯一節點,這樣每次節點路徑改變時,就不用再去更新腳本。
建立與使用
有兩種方式可以建立場景唯一節點。
在場景樹面板中,於節點上點擊右鍵,並在右鍵選單選擇 作為唯一名稱存取。
選擇此選項後,該節點在場景樹中的名稱旁邊會出現百分號(%):
你也可以在重新命名節點時,於名稱開頭加上「%」來達成。確認後,名稱旁邊會自動顯示百分號。
現在你可以在腳本中使用這個節點。例如,你可以在呼叫 get_node() 時,輸入 % 符號接著節點名稱來引用它:
get_node("%RedButton").text = "Hello"
%RedButton.text = "Hello" # Shorter syntax
GetNode<Button>("%RedButton").Text = "Hello";
同場景限制
場景唯一節點只能被同一個場景內的節點取得。為了說明此限制,以下是一個 Player 場景實例化 Sword 場景的範例:
以下是在 Player 腳本內呼叫 get_node() 的結果:
get_node("%Eyes")會回傳 Eyes 節點。get_node("%Hilt")會回傳null。
以下是在 Sword 腳本內呼叫 get_node() 的結果:
get_node("%Eyes")會回傳null。get_node("%Hilt")會回傳 Hilt 節點。
如果腳本能取得另一個場景的節點,就可以在該節點上呼叫 get_node(),以取得該場景中的場景唯一節點。這同樣適用於節點路徑,可以避免重複呼叫 get_node()。以下是在 Player 腳本中使用場景唯一節點取得 Hilt 節點的兩種寫法:
get_node("Hand/Sword").get_node("%Hilt")會回傳 Hilt 節點。get_node("Hand/Sword/%Hilt")也會回傳 Hilt 節點。
場景唯一名稱不只可以用在節點路徑的最末端,也可以在中間使用,讓你從一個節點導覽到另一個節點。例如,Sword 節點在 Player 場景中被設為場景唯一節點,因此你可以這樣寫:
get_node("%Sword/%Hilt")會回傳 Hilt 節點。
其他方法
場景唯一節點是導覽場景很實用的工具,不過在某些情況下,其他技巧可能會更適合。
群組 可以讓你從任何節點定位另一個節點(或多個節點),無論它們分屬於哪個場景。
單例(自動載入) 是一個無論在哪個場景都會載入的節點,任何節點都可以直接存取它。當有資料或功能需要全域共用時,這會很有用。
Node.find_child() 可以透過名稱找到節點,而不需要知道完整路徑。這看似和場景唯一節點類似,但它能找到巢狀場景中的節點,而且不需在場景編輯器中特別標記。不過這個方法較慢,因為 Godot 會快取場景唯一節點、查找速度快,但每次呼叫 find_child() 時都必須檢查所有子代(每個孩子、孫節點等)。