[GODOT]获取节点

本篇主要记录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)

在上面的代码中,第二行中的 @"." 将返回一个 NodePathget_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,我们便可以在编辑器中选择一个节点

也可以在其他脚本中设置这个变量,这将会把我们从高耦合的设计中解救出来,帮助你完成更加健康,灵活的框架。

posted @ 2021-11-02 19:33  Smalldy  阅读(2609)  评论(0编辑  收藏  举报