使用 move_and_slide 移动实例化播放器

Moving an instanced player with move_and_slide

我可能想多了,或者以完全错误的方式去做。基本上我想在我评论#MOVE 的实例播放器 (aPlayer) 上使用 move_and_slide。此脚本附加到实例化场景 Level_Test.

上的我的 Tilemap

为此 post 缩减了屏幕截图中的代码,因为它目前不相关且不起作用。

extends TileMap

onready var aPlayer = preload("res://Scenes/Player.tscn").instance()

var cSpawn1 = Vector2.ZERO

func _ready() -> void:
    aPlayer.position = cSpawn1
    add_child(aPlayer)

func _physics_process(delta) -> void:
    if Input.is_action_just_released("iPlayerInteract"):
        _Interact()
    else:
        var vInputDirection = Vector2(Input.get_action_strength("iPlayerRight") - Input.get_action_strength("iPlayerLeft"), Input.get_action_strength("iPlayerDown") - Input.get_action_strength("iPlayerUp"))
        if vInputDirection != Vector2.ZERO:
            _Move(aPlayer, vInputDirection)

func _Interact():
    pass

func _Move(vSelf, vDirection):
    #MOVE
    pass

截图中的player.tscn场景结构如下:

Player (Node2d)
└ Body (KinematicBody2D)
  ├ Camera (Camera2D)
  ├ Collision (CollisionShape2D)
  └ Sprite (Sprite)

这是此处实例化的内容:

onready var aPlayer = preload("res://Scenes/Player.tscn").instance()

aPlayer设置为实例场景的根节点,即Node2D

因此您传递给 _Move (_Move(aPlayer, vInputDirection)) 的是 Node2D,它没有 move_and_slide,因此调用 move_and_slide它会导致错误。

相反 move_and_slide 存在于 KinematicBody(3D) and KinematicBody2D

简单而优雅的解决方案是将 KinematicBoyd2D (Body) 作为场景的根。 二次单击“场景”面板时出现的上下文菜单中有一个“制作场景根目录”。

或者您也可以使用 get_node 进入场景,例如:

vSelf.get_node("Body").move_and_slide(...)

或者例如:

onready var aPlayer = preload("res://Scenes/Player.tscn").instance().get_node("Body")

附录:你想想还有一个办法。您可以将脚本添加到根节点 (Player) 并在那里声明您想要的任何函数,包括但不限于委托给 KinematicBody2D (Body ).

我还应该指出,move_and_slide 会移动 KinematicBody2D,但不会移动其父级。所以Player节点上的position属性将不再是KinematicBody2D的位置。而且,如果将 KinematicBody2D 设置为根目录,就可以避免所有麻烦。