📅  最后修改于: 2023-12-03 15:01:01.010000             🧑  作者: Mango
在 Godot 中,Raycast2D 是一个非常有用的工具,可以用于检测场景中的碰撞体。不过,默认情况下,Raycast2D 只会检测其父节点的子节点,可能会导致一些问题。本文将介绍如何让 Raycast2D 不排除父级节点来解决这些问题。
假设我们有一个场景,其中包含一个主角和两个墙壁。主角可以在场景中移动,我们希望在主角碰到墙壁时停止移动。我们可以使用 Raycast2D 来检测碰撞体,如下所示:
extends KinematicBody2D
onready var raycast = $RayCast2D
func _physics_process(delta):
var motion = Vector2.ZERO
var direction = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
motion.x += 1
direction.x = 1
elif Input.is_action_pressed("ui_left"):
motion.x -= 1
direction.x = -1
if Input.is_action_pressed("ui_down"):
motion.y += 1
direction.y = 1
elif Input.is_action_pressed("ui_up"):
motion.y -= 1
direction.y = -1
motion = motion.normalized() * speed * delta
motion = move_and_slide(motion, FLOOR_NORMAL)
var result = raycast.get_collider()
if result != null:
print("Hit:", result.name)
这段代码创建了一个 KinematicBody2D,用于控制主角运动。Raycast2D 位于主角的子节点中(也可以是其他节点),用于检测主角与周围物体的碰撞。在 _physics_process 函数中,使用 Raycast2D.get_collider() 来获取射线检测到的碰撞体。
问题在于,由于 Raycast2D 只会检测其父节点的子节点,所以它不能检测主角与墙壁之间的碰撞。因为墙壁不是主角节点的子节点,所以 Raycast2D 可能无法正确检测到它。
为了解决这个问题,我们需要让 Raycast2D 能够检测到父节点以外的子节点。Godot 提供了一个名为 collision_mask 的属性来指定哪些节点会被检测。默认情况下,collision_mask 是 1,表示只检测节点的子节点。我们可以将 collision_mask 设置为 -1,表示检测所有节点。修改代码如下:
extends KinematicBody2D
onready var raycast = $RayCast2D
func _ready():
raycast.collision_mask = -1 # 修改 collision_mask
func _physics_process(delta):
var motion = Vector2.ZERO
var direction = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
motion.x += 1
direction.x = 1
elif Input.is_action_pressed("ui_left"):
motion.x -= 1
direction.x = -1
if Input.is_action_pressed("ui_down"):
motion.y += 1
direction.y = 1
elif Input.is_action_pressed("ui_up"):
motion.y -= 1
direction.y = -1
motion = motion.normalized() * speed * delta
motion = move_and_slide(motion, FLOOR_NORMAL)
var result = raycast.get_collider()
if result != null:
print("Hit:", result.name)
这样,Raycast2D 就可以检测主角与墙壁之间的碰撞了。
Godot 中的 Raycast2D 很强大,但默认情况下只会检测其父节点的子节点。如果需要检测父节点以外的节点,可以修改 collision_mask 属性来完成。