【问题标题】:Godot: Call external methodGodot:调用外部方法
【发布时间】:2021-05-22 23:16:56
【问题描述】:

大量谷歌搜索,但我仍然不明白什么可能是一个简单的解决方案。

场景:“主要”。包含一个 TileMap“Grid”,并附有一个脚本“Grid.gd”。

场景:“玩家”。包含一个带有脚本的 KinematicBody2D“Player”“Player.gd”

在 Player.gd 中,我需要调用 Grid.gd 中的一个方法“_Calculate”,将两个变量传递给它,并让它返回一个变量。

var vNewPosition = Grid._Calculate(vPlayer, vInputDirection)

错误:标识符“Grid”未在当前范围内声明。

显然我需要在某个地方引用 Grid.gd 脚本才能访问它,但我尝试过的许多示例都没有工作。

提前致谢, 乔什

【问题讨论】:

  • “主”场景是否也包含“玩家”场景?如果不是,这些场景有什么关系?
  • 它们是不同的场景。 Main 场景有一个 Player 场景的实例。基本上会有多个场景(关卡),所有的场景都使用了玩家场景的一个实例。

标签: godot


【解决方案1】:

鉴于此

主场景有一个玩家场景的实例

在 Player.gd 中,我需要调用 Grid.gd 中的一个方法“_Calculate”,将两个变量传递给它,并让它返回一个变量。

我会给你几个选择。


不好的方式

如果 Player 知道 Grid 的节点路径,它可以使用get_node 来获取它。

onready var _grid = get_node("../../grid")

或者类似的东西。

然后使用它:

var vNewPosition = _grid._Calculate(vPlayer, vInputDirection)

这种方法当然不推荐。如果节点路径错误,它将中断。


常用方式

假设 Player 不知道节点路径(这种可能性更大),您可以在 Player.gd 中导出一个NodePath 变量并使用它来获取 Grid:

exprort var grid_path:NodePath
onready var _grid = get_node(grid_path)

然后需要将Main场景中的Grid Path属性设置为Grid。

这种方法比前一种方法更好,因为它不依赖于 Grid 的路径。但是,它仍然取决于存在的网格。如果没有 Grid 时 Player 没有意义,这种方法是可以的。


好办法

如果 Grid 可能存在也可能不存在,并且我们希望 Player 能够正常工作,我们可以调整上述方法:

exprort var grid_path:NodePath
onready var _grid = get_node_or_null(grid_path)

记得在使用前检查grid是否为null:

if grid == null:
    return # or whatever

var vNewPosition = grid._Calculate(vPlayer, vInputDirection)

或者像这样:

var vNewPosition = grid._Calculate(vPlayer, vInputDirection) if grid != null else null

这也允许我们指定vNewPosition 在没有网格时将采用的默认值(行尾的null)。因此,您可以让 Player 在没有 Grid 的情况下工作,当有 Grid 时,它会使用,无论在哪里(因为 Main 告诉它它在哪里)。

这个解决方案没有完全解耦,因为 Player 仍然知道 grid 是一个有 _Calculate 的东西。我们还假设有零或一,而不是多个。我可以想办法解决这个问题,但为了解耦而解耦是不必要的。我认为这对您的用例来说已经足够好了。但是,如果您想要过度设计的方式,请告诉我。

【讨论】:

  • 对可用选项的出色总结。当然,“真正”的答案是使用信号并使其使玩家永远不需要从网格中获得响应(即,与其让玩家在移动之前检查网格方块是否为空,不如让玩家发出信号说“我想搬到这里”,让网格自己检查)。但是,当然,这种方法需要某种范式转变,而我自己也在适应这一点。导出的NodePath 是一个很好的折衷方案,它允许人们以他们可能熟悉的方式进行编程。
  • @SilvioMayolo 对。顺便提一下,emit_signal 不会返回,也不会等待连接的方法完成(也不关心它们是否屈服)。如果播放器脚本需要结果,则需要一个信号让网格重放,或者我发现很难证明这种情况的其他方法,但它是完全可行的。编辑:我还通过 set_grid 函数跳过了更传统的依赖注入,这确实不是惯用的 Godot。
  • 感谢您的时间和投入。显然,我试图避免网格信号,因为我不熟悉这种心态。我将尝试给出的示例并考虑是否需要重新调整以适应这种不同的思维方式,或者可以按照我习惯的方式做我想做的事。再次感谢!
猜你喜欢
  • 2020-03-06
  • 2017-03-08
  • 1970-01-01
  • 2013-09-24
  • 2021-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多