📜  godot raycast2d 不排除父级 (1)

📅  最后修改于: 2023-12-03 15:01:01.010000             🧑  作者: Mango

Godot Raycast2D 不排除父级

在 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 属性来完成。