使用 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
设置为根目录,就可以避免所有麻烦。
我可能想多了,或者以完全错误的方式去做。基本上我想在我评论#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
设置为根目录,就可以避免所有麻烦。