如何解决将 KinematicBody2D 移动到已知位置godot
我在 godot 和物理过程中制作了一个平台游戏,我正在获取玩家的位置,以便我可以将敌人移动到它(它在敌人的脚本中,但我无法弄清楚如何使用 {{1}获取位置 但是当我向玩家移动并滑动时,它给了我一个错误。(顺便说一句,这是一个平台游戏,所以如果该方法增加了重力会很好)
基础“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 numeric_inertia=true )
注意:
- 第一个参数是一个速度向量。
- 第二个参数是一个向上向量。
因此,此功能不适用于职位。
你得到的错误是因为你在 up 参数上传递了一个浮点数。
为什么 move_and_slide
使用 up 向量?这是因为 move_and_slide
更新了您从 is_on_ceiling
、is_on_floor
和 is_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.origin
或 position
,因为它们是相对于父节点的。如果父母不一样,你就会得到一个错误的方向。 *我倾向于使用变换,因为
还请注意,我在 is_on_floor
之后使用了 move_and_slide
,因此我获得了更新后的值。我强烈鼓励这种模式:重力、移动和滑动、决策。
这不会跳或爬梯子或类似的东西。它也会卡在墙上。它与寻路或避障没有任何相似之处。因此,正如您想象的那样,根据您想要做什么,它可能会变得非常复杂。然而,它从那里成长。我对您想要赋予这些运动学体的行为知之甚少,除此之外,您希望它们使用 mode_and_slide
和重力传递给玩家,我不知道。因此,我无法进一步帮助您。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。