You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Raycast2D仅能在起点检测碰撞,末端检测失效求助

Raycast2D仅在起点检测碰撞,末端无法检测的问题解决

我在使用Raycast2D检测与敌方单位的碰撞时遇到问题:仅能在射线起点检测到碰撞,末端无法检测到碰撞。以下是我的代码:

extends KinematicBody2D

export var speed = 200
var velocity = Vector2.ZERO
var enemy = 0

onready var navigation_agent = $NavigationAgent2D
onready var bullet = preload("res://Bullet.tscn").instance()

func _ready():
    navigation_agent.connect("velocity_computed", self, "move")
    $RayCast2D.global_rotation = self.global_rotation - 90

func _input(event):
    if event.is_action_pressed("mouse_right"):
        navigation_agent.set_target_location(event.get_global_position())

func _process(_delta):
    if $RayCast2D.is_colliding():
        if $RayCast2D.get_collider().is_in_group("enemy_ground_troop"):
            enemy = $RayCast2D.get_collider()
            velocity = Vector2.ZERO
            ranged_attack()

    if navigation_agent.is_navigation_finished():
        return
    
    velocity = global_position.direction_to(navigation_agent.get_next_location()) * speed

    look_at(navigation_agent.get_next_location())

    navigation_agent.set_velocity(velocity)

func move(velocity):
    velocity = move_and_slide(velocity)

func ranged_attack():
    add_child(bullet)
    bullet.global_position = self.global_position
    
    bullet.target = enemy.global_position

问题排查与解决方法

  • 检查射线长度:选中RayCast2D节点,确认Cast To属性的向量长度足够,确保射线能覆盖到需要检测的敌方单位范围。如果这个向量长度过小,射线无法延伸,自然只能检测起点附近的碰撞。
  • 修正旋转角度单位:Godot中旋转属性使用弧度而非度数,你当前代码里的self.global_rotation - 90会导致旋转角度严重错误,应改为:
    $RayCast2D.global_rotation = self.global_rotation - deg2rad(90)
    
    这样才能正确将射线旋转90度,指向目标方向。
  • 排除自身碰撞:确认RayCast2D的Exclude Parent属性已勾选,避免射线优先检测到自身的KinematicBody2D,导致起点碰撞误触发。
  • 匹配碰撞层与掩码:检查RayCast2D的Collision Mask是否包含敌方单位所在的碰撞层,同时敌方单位的Collision Layer要与射线的掩码对应,否则射线会忽略敌方单位。
  • 修复子弹实例逻辑:当前代码在_ready()中提前实例化子弹,重复添加同一节点会导致异常,应改为每次攻击时重新实例化:
    func ranged_attack():
        var new_bullet = preload("res://Bullet.tscn").instance()
        add_child(new_bullet)
        new_bullet.global_position = self.global_position
        new_bullet.target = enemy.global_position
    
  • 调整检测到物理帧:将RayCast2D的碰撞检测逻辑移到_physics_process中执行,因为碰撞属于物理相关操作,在物理帧中运行会更准确,避免帧率波动导致的检测遗漏:
    func _physics_process(_delta):
        if $RayCast2D.is_colliding():
            if $RayCast2D.get_collider().is_in_group("enemy_ground_troop"):
                enemy = $RayCast2D.get_collider()
                velocity = Vector2.ZERO
                ranged_attack()
    

内容的提问来源于stack exchange,提问作者AbsolutePickle42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:35:20