Godot:如何将 KinematicBody2D 节点从一个场景移动到另一个场景

Godot: How to move KinematicBody2D node from one scene to another

我想将我的 Player 节点 (KinematicBody2D) 从一个场景移动到另一个场景。我的代码成功移动了 Node2D 节点,但使用 KinematicBody2D 节点失败了。

我有两个具有以下结构的位置场景(继承自基本位置场景):

FirstLocation (inherits Location)
  - YSort
    - Player

在基础Location场景中我有两种方法:

func add_player(player: Player):
    get_node("YSort").add_child(player)

func remove_player() -> Player:
    var player = get_node("YSort/Player")
    get_node("YSort").remove_child(player)
    return player

GameWorld 场景中,我将可能的位置存储在字典中,玩家的移动发生在 change_location() 函数中:

onready var _locations = {
    Location.FOO: $CurrentLocation,
    Location.BAR: load("res://locations/Bar.tscn").instance(),
}

onready var _current_location = $CurrentLocation

func change_location(location: int):
    var player = _current_location.remove_player()

    remove_child(_current_location)
    _current_location = _locations[location]
    add_child(_current_location)

    _current_location.add_player(player)

但是当 Player 是 KinematicBody2D 时,游戏就会崩溃,没有提示我是什么导致了问题。

当我注释掉最后一行时,代码可以正常工作而不会崩溃:

    _current_location.add_player(player)

...但是当然玩家不会被添加到另一个场景中。

KinematicBody2D 中有什么阻止我将它从一个场景移动到另一个场景?


找到了解决方法,但不知道为什么有效。

我正在执行位置更改作为对 Area2D.body_entered 信号的响应。我触发了自己的信号“location_change”,然后在代码的另一部分调用了change_location()函数来响应它。

在进行位置更改之前添加一个微小的超时(0.00000001 秒)解决了这个问题。但是我不知道为什么,我很确定添加超时不是解决这个问题的正确方法。

我无法想象情况。但是考虑到问题发生在移除和添加物理体时,并且涉及"body_entered",并且您找到的解决方案是添加超时…

听起来问题是在 Godot 仍在解析物理响应时移除了物理体。然后解决方案就是等到下一帧。

您可以等到下一个图形帧:

yield(get_tree(), "idle_frame")

或者直到下一个物理框架:

yield(get_tree(), "physics_frame")

这比一些任意的小超时要好。


或者,您也可以延迟信号连接。

如果您从 UI 进行连接,“将信号连接到方法”对话框中将有一个“高级”开关。启用“高级”切换将显示一些额外的内容,包括延迟连接。

如果您正在连接表单代码,您可以通过传递 CONNECT_DEFERRED 标志来完成同样的事情。