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.
Checking the stable version of the documentation...
场景唯一节点
前言
在脚本中使用 get_node()
来引用节点在某些情况下可能比较脆弱。如果你把 UI 场景里的某个按钮移到了别的面板里,那么这个按钮的节点路径就会发生改变,而如果脚本中正好使用了写死的节点路径来调用 get_node()
,那这样一来这个脚本就无法再找到这个按钮了。
类似这种情况,可以将节点设为场景唯一节点,这样该节点的路径发生变化时就不必再更新脚本了。
创建与使用
There are two ways to create a scene unique node.
在场景树面板中,右键单击节点并在上下文菜单中选择作为唯一名称访问。

勾选后,场景树中该节点的名称旁边就会显示一个百分号(%):

You can also do this while renaming the node by adding "%" to the beginning of the name. Once you confirm, the percent symbol will appear next to its name.
现在你就可以在脚本中使用这个节点了。例如先打一个 % 符号,在后面跟上节点的名称,这样就可以使用 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 节点。
场景唯一名称不止可以用在节点路径的末尾,也可以用在路径的中间来实现跳转。例如 Player 场景中的 Sword 节点就是一个场景唯一节点,因此可以这样写:
get_node("%Sword/%Hilt")
会返回 Hilt 节点。
替代方案
使用场景唯一节点可以很方便地在场景中进行跳转。但是有些情况下其他写法会更好一些。
使用分组可以从任意节点定位到某个节点(或一组节点),无需考虑所处的场景。
单例(自动加载)是一种始终存在的节点,任何节点都可以直接访问,无需考虑所处的场景。适合需要全局共享数据或功能的时候使用。
Node.find_child() 可以根据名称来查找节点,无需知道完整路径。这种做法看上去和场景唯一节点类似,并且可以查找到嵌套场景里的节点,也不需要在场景编辑器里标记节点。但是这个方法相对较慢。Godot 会缓存场景唯一节点,所以获取的时候比较快,而调用 find_child()
时则需要查找每一个后代节点(子节点、孙节点等)。