本篇主要記錄godot獲取節點的方法或技巧。
NodePath
NodePath 在將一個節點作為參數導出時非常有用,它會減少此腳本與場景中其他節點的耦合性,保證你構建一個“可以單獨運行的場景”。NodePath的表達方式類似一個文件路徑,這與GoDot的節點設計哲學十分相符,你可以很簡單的通過路徑表達方式來確定一個節點。在我列出這些表示方法之前,請注意這些路徑的起始為止為腳本所依附的那個節點。
為了更加清晰的表述,現在我設定一個節點結構。如圖所示:
當前腳本掛載在Bullet上
NodePath 表示/語法
使用 @"xxx/xxx/xxx" 可以獲得一個NodePath變量,除了導出節點時,你通常不會直接使用這個類型,想要獲取一個節點時,一般地,可以使用 Node get_node(path: NodePath) const
方法:
# 將會輸出 Bullet
print(get_node(@".").name)
# 將會輸出 Bullet
print(get_node(".").name)
在上面的代碼中,第二行中的 @"."
將返回一個 NodePath
,get_node
返回指定的節點,print
輸出其名稱。值得注意的是,由於NodePath可以通過字符串直接構造,在第4行中,字符串通過隱式轉換構造為 NodePath
,從而也能夠正確的調用get_node
。
我們可以在官方文檔中,找到一個比較全面的NdePath
的各種寫法:
# 沒有路徑前綴表示此路徑是相對於當前節點的 @"A" #子節點A @"A/B" # A的子節點B @"." # 當前節點 @".." # 父節點 @"../C" # 兄弟節點C # 攜帶前綴路徑表示場景樹的絕對路徑 @"/root" # 等同於 get_tree().get_root() @"/root/Main" # 主場景——"Main"(假設主場景的名字為Main) @"/root/MyAutoload" # 自動加載腳本——MyAutoload(如果有)
當然,為了更加快捷,建議使用GoDot提供的語法糖,$
:
print($".".name) # 與print(get_node(".").name) 一致
print($"Sprite".name) # 與print(get_node("Sprite").name) 一致
進一步地,有更加方便的寫法來獲取子節點:
print($Sprite.name)
export
對於一個場景來說,我們應盡力降低與其他節點的依賴,在腳本中直接指定其他節點將會造成兩個節點的高耦合,使用export可以將NodePath進行導出,從而解決強依賴問題。
例如,子彈需要記錄子彈的發射者,用於之后在擊中時進行傷害判定,因此我們需要在腳本中獲取子彈的發射者,如果將發射者硬編碼,寫死,將會導致子彈節點無法通用,這種子彈只能從你指定的節點上發射了。
值得慶幸的是,我們還有轉機:
export(NodePath) var who_shoot_me
在腳本中導出NodePath,我們便可以在編輯器中選擇一個節點
也可以在其他腳本中設置這個變量,這將會把我們從高耦合的設計中解救出來,幫助你完成更加健康,靈活的框架。