将 KinematicBody2D 移动到已知位置 (godot)

Move a KinematicBody2D to a known location (godot)

我在 godot 中制作了一个平台游戏,在物理过程中我得到了玩家的位置,所以我可以将敌人移动到它那里(它在敌人的脚本中但我不知道如何将它移动到那里我使用 get_node("/root/World/Player").get_position() 获取位置 但是当我向玩家移动并滑动时,它给了我一个错误。(顺便说一句,它是一个平台游戏,所以如果该方法增加重力会很好)

基 'KinematicBody2D (enemy.gd)' 中的类型函数 'move_and_slide' 无效。无法将参数 2 从 float 转换为 Vector2。

(如果这样就好了

让我们从 documentation of move_and_slide 开始。这是函数的签名:

Vector2 move_and_slide ( Vector2 linear_velocity, Vector2 up_direction=Vector2( 0, 0 ), bool stop_on_slope=false, int max_slides=4, float floor_max_angle=0.785398, bool infinite_inertia=true )

通知:

  • 第一个参数是一个速度向量。
  • 第二个参数是一个up向量。

因此,此功能不适用于职位。

你得到的错误是因为你在 up 参数上传递了一个浮点数。


为什么 move_and_slide 需要向上矢量?这是因为 move_and_slide 更新了您从 is_on_ceilingis_on_flooris_on_wall 获得的值。它怎么知道什么是天花板、地板或墙壁?没错,它需要知道它的上升方向。如果你让向上向量为零(或者只是不通过它,因为这是默认值),它们都被认为是墙(这对于自上而下的游戏来说是可以的)。


现在,您想做一款平台游戏,大概是一款横向卷轴游戏。您很可能想将 Vector2.UP 作为第二个参数传递。这应该可以修复错误。


但是,您在里面偷偷提出了另一个问题。一个更适合 gamedev.stackexchange.com您可以在那里提问(不一定是您遇到错误)。

因此,您想要实现一个具有重力的运动体来追逐玩家。让我们从重力开始……

具有重力的运动体的铣削代码 运行 如下所示:

extends KinematicBody2D

export(Vector2) var velocity:Vector2
export(float) var gravity:float = 100

func _physics_process(delta:float) -> void:
    velocity.y += gravity * delta
    velocity = move_and_slide(velocity, Vector2.UP)

好吧,gravity可能不是100。但这是代码的基本结构。请注意距离单位 - 作为 2D 游戏 - 以像素为单位,delta 以秒为单位。因此,gravity 以每秒平方像素为单位。


而且你想追玩家头像。为了实现这一点,我将进行以下更改:

  • 引用玩家头像。
  • 将速度分成垂直和水平分量。
  • 有水平速度。
extends KinematicBody2D

export(NodePath) var player_path:NodePath = @"/root/World/Player"
export(float) var horizontal_speed:float = 100
export(float) var gravity:float = 100

onready var player:Node2D = get_node(player_path)
var _velocity:float = 0

func _physics_process(delta:float) -> void:
    _velocity.y += gravity * delta
    _velocity = move_and_slide(_velocity, Vector2.UP)
    var direction_to_player = transform.origin.direction_to(player.transform.origin)
    _velocity.x = direction_to_player.x * horizontal_speed

此代码使用 NodePath 来查找玩家头像。它在准备就绪时查询,并从那里使用该引用。假设玩家总是在那里,那没问题。

horizontal_speed 指定它向玩家水平移动的速度。 以像素/秒为单位。

如果你不希望它在空中改变速度,我们也可以这样做:

extends KinematicBody2D

export(NodePath) var player_path:NodePath = @"/root/World/Player"
export(float) var horizontal_speed:float = 100
export(float) var gravity:float = 100

onready var player:Node2D = get_node(player_path)
var _velocity:Vector2 = Vector2.ZERO

func _physics_process(delta:float) -> void:
    _velocity.y += gravity * delta
    _velocity = move_and_slide(_velocity, Vector2.UP)
    if is_on_floor():
        var direction_to_player = global_transform.origin.direction_to(player.global_transform.origin)
        _velocity.x = direction_to_player.x * horizontal_speed

注意我正在使用 global_transform.origin。您也可以使用 global_position。不要使用 transform.originposition,因为它们是相对于 parent 节点的。如果 parent 不一样,你就会走错方向。 *我偏向于使用变换因为

还请注意,我在 move_and_slide 之后使用了 is_on_floor,所以我得到了更新后的值。我强烈鼓励这种模式:重力,move_and_slide,决定。

这不会跳或爬梯子或类似的东西。它还会卡在墙上。它与寻路或避障没有任何相似之处。因此,正如您所想象的那样,它可能会变得非常复杂,具体取决于您想要做什么。但是,它是从那里生长的。我对您想赋予这些运动机构的行为知之甚少,除此之外,您希望它们使用 mode_and_slide 和重力作用于玩家,我不知道。因此,我无法进一步帮助您。